[libxslt] Fix problems with embedded stylesheets and namespaces



commit 34c7b5ce635afbf68ce1dc33f92e72d76909dc6f
Author: Martin <gzlist googlemail com>
Date:   Thu Sep 17 10:22:42 2009 +0200

    Fix problems with embedded stylesheets and namespaces
    
    * libxslt/xslt.c: copy the embedded stylesheet instead of cutting it
      out of the source tree and make sure to copy namespaces in scope too
    * tests/REC/Makefile.am tests/REC/stand-2.7-[23]*: add the 2 tests
      case to the regression suite

 libxslt/xslt.c                  |   42 ++++++++++++++++++++++++++++++--------
 tests/REC/Makefile.am           |    3 +-
 tests/REC/stand-2.7-2.stand.out |    8 +++++++
 tests/REC/stand-2.7-2.xml       |    9 ++++++++
 tests/REC/stand-2.7-3.stand.out |    8 +++++++
 tests/REC/stand-2.7-3.xml       |    9 ++++++++
 6 files changed, 69 insertions(+), 10 deletions(-)
---
diff --git a/libxslt/xslt.c b/libxslt/xslt.c
index c289a9f..55f505b 100644
--- a/libxslt/xslt.c
+++ b/libxslt/xslt.c
@@ -6912,8 +6912,14 @@ xsltLoadStylesheetPI(xmlDocPtr doc) {
 		    "xml-stylesheet : no ID %s found\n", URI->fragment);
 	    } else {
 		xmlDocPtr fake;
-		xmlNodePtr subtree;
+		xmlNodePtr subtree, newtree;
+		xmlNsPtr ns;
 
+#ifdef WITH_XSLT_DEBUG
+		xsltGenericDebug(xsltGenericDebugContext,
+		    "creating new document from %s for embedded stylesheet\n",
+		    doc->URL);
+#endif
 		/*
 		 * move the subtree in a new document passed to
 		 * the stylesheet analyzer
@@ -6921,20 +6927,38 @@ xsltLoadStylesheetPI(xmlDocPtr doc) {
 		subtree = ID->parent;
 		fake = xmlNewDoc(NULL);
 		if (fake != NULL) {
-                    /*
-		     * the dictionary should be shared since nodes are
-		     * moved over.
-		     */
+		    /*
+		    * Should the dictionary still be shared even though
+		    * the nodes are being copied rather than moved?
+		    */
 		    fake->dict = doc->dict;
 		    xmlDictReference(doc->dict);
 #ifdef WITH_XSLT_DEBUG
 		    xsltGenericDebug(xsltGenericDebugContext,
-                         "reusing dictionary from %s for stylesheet\n",
-			 doc->URL);
+			"reusing dictionary from %s for embedded stylesheet\n",
+			doc->URL);
+#endif
+
+		    newtree = xmlDocCopyNode(subtree, fake, 1);
+
+		    fake->URL = xmlNodeGetBase(doc, subtree->parent);
+#ifdef WITH_XSLT_DEBUG
+		    xsltGenericDebug(xsltGenericDebugContext,
+			"set base URI for embedded stylesheet as %s\n",
+			fake->URL);
 #endif
 
-		    xmlUnlinkNode(subtree);
-		    xmlAddChild((xmlNodePtr) fake, subtree);
+		    /*
+		    * Add all namespaces in scope of embedded stylesheet to
+		    * root element of newly created stylesheet document
+		    */
+		    while ((subtree = subtree->parent) != (xmlNodePtr)doc) {
+			for (ns = subtree->ns; ns; ns = ns->next) {
+			    xmlNewNs(newtree,  ns->href, ns->prefix);
+			}
+		    }
+
+		    xmlAddChild((xmlNodePtr)fake, newtree);
 		    ret = xsltParseStylesheetDoc(fake);
 		    if (ret == NULL)
 			xmlFreeDoc(fake);
diff --git a/tests/REC/Makefile.am b/tests/REC/Makefile.am
index 2c372db..cae04f4 100644
--- a/tests/REC/Makefile.am
+++ b/tests/REC/Makefile.am
@@ -72,7 +72,8 @@ EXTRA_DIST = 						\
     test-9.1-2.out test-9.1-2.xml test-9.1-2.xsl	\
     test-9.2-1.xsl					\
     stand-2.7-1.dtd stand-2.7-1.stand.out stand-2.7-1.xsl \
-    stand-2.7-1.out  stand-2.7-1.xml
+    stand-2.7-1.out stand-2.7-1.xml			\
+    stand-2.7-2.xml stand-2.7-3.xml
 
 
 all:
diff --git a/tests/REC/stand-2.7-2.stand.out b/tests/REC/stand-2.7-2.stand.out
new file mode 100644
index 0000000..49a4cf8
--- /dev/null
+++ b/tests/REC/stand-2.7-2.stand.out
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<xmp:moop xmlns:xmp="http://example.com/ns"; xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
+	<xsl:transform id="transform" version="1.0">
+		<xsl:template match="/xmp:moop">
+			<xsl:copy-of select="."/>
+		</xsl:template>
+	</xsl:transform>
+</xmp:moop>
diff --git a/tests/REC/stand-2.7-2.xml b/tests/REC/stand-2.7-2.xml
new file mode 100644
index 0000000..22e6834
--- /dev/null
+++ b/tests/REC/stand-2.7-2.xml
@@ -0,0 +1,9 @@
+<!DOCTYPE xmp:moop [<!ATTLIST xsl:transform id ID #IMPLIED>]>
+<?xml-stylesheet type="text/xsl" href="#transform"?>
+<xmp:moop xmlns:xmp="http://example.com/ns"; xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
+	<xsl:transform id="transform" version="1.0">
+		<xsl:template match="/xmp:moop">
+			<xsl:copy-of select="."/>
+		</xsl:template>
+	</xsl:transform>
+</xmp:moop>
diff --git a/tests/REC/stand-2.7-3.stand.out b/tests/REC/stand-2.7-3.stand.out
new file mode 100644
index 0000000..49a4cf8
--- /dev/null
+++ b/tests/REC/stand-2.7-3.stand.out
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<xmp:moop xmlns:xmp="http://example.com/ns"; xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
+	<xsl:transform id="transform" version="1.0">
+		<xsl:template match="/xmp:moop">
+			<xsl:copy-of select="."/>
+		</xsl:template>
+	</xsl:transform>
+</xmp:moop>
diff --git a/tests/REC/stand-2.7-3.xml b/tests/REC/stand-2.7-3.xml
new file mode 100644
index 0000000..a8c8362
--- /dev/null
+++ b/tests/REC/stand-2.7-3.xml
@@ -0,0 +1,9 @@
+<!DOCTYPE xmp:moop [<!ATTLIST xsl:transform id ID #IMPLIED>]>
+<?xml-stylesheet type="text/xsl" href="#transform"?>
+<xmp:moop xmlns:xmp="http://example.com/ns"; xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
+	<xsl:transform id="transform" version="1.0" xmlns:xmp="http://example.com/ns";>
+		<xsl:template match="/xmp:moop">
+			<xsl:copy-of select="."/>
+		</xsl:template>
+	</xsl:transform>
+</xmp:moop>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]