added code to assure keys are generated when needed for node-sets (bug
authorWilliam M. Brack <wbrack@src.gnome.org>
Mon, 2 Aug 2004 15:51:00 +0000 (15:51 +0000)
committerWilliam M. Brack <wbrack@src.gnome.org>
Mon, 2 Aug 2004 15:51:00 +0000 (15:51 +0000)
* libxslt/documents.c, libxslt/functions.c, libxslt/transform.c,
  libxslt/variables.c: added code to assure keys are generated
  when needed for node-sets (bug 148773)
* tests/exslt/common/node-set.7.* - added test case for above.

ChangeLog
libxslt/documents.c
libxslt/functions.c
libxslt/transform.c
libxslt/variables.c
tests/exslt/common/Makefile.am
tests/exslt/common/node-set.7.out [new file with mode: 0644]
tests/exslt/common/node-set.7.xml [new file with mode: 0644]
tests/exslt/common/node-set.7.xsl [new file with mode: 0644]

index 2b43575..ac61ff1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Mon Aug  2 08:48:03 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+       * libxslt/documents.c, libxslt/functions.c, libxslt/transform.c,
+         libxslt/variables.c: added code to assure keys are generated
+         when needed for node-sets (bug 148773)
+       * tests/exslt/common/node-set.7.* - added test case for above.
+
 Mon Jul 26 17:03:22 PDT 2004 William Brack <wbrack@mmm.com.hk>
 
        * libexslt/strings.c: fixed str:tokenize for case when 2nd
index c4e4b36..a30374a 100644 (file)
@@ -63,8 +63,10 @@ xsltNewDocument(xsltTransformContextPtr ctxt, xmlDocPtr doc) {
     memset(cur, 0, sizeof(xsltDocument));
     cur->doc = doc;
     if (ctxt != NULL) {
-       cur->next = ctxt->docList;
-       ctxt->docList = cur;
+        if (!xmlStrEqual((xmlChar *)doc->name, BAD_CAST " fake node libxslt")) {
+           cur->next = ctxt->docList;
+           ctxt->docList = cur;
+       }
        xsltInitCtxtKeys(ctxt, cur);
     }
     return(cur);
index ad839cc..aa1a236 100644 (file)
@@ -437,12 +437,30 @@ xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){
        oldDocumentPtr = tctxt->document;
        oldXPathDocPtr = tctxt->xpathCtxt->doc;
        if ((ctxt->context->doc != NULL) &&
-           (tctxt->document->doc != ctxt->context->doc)) {
-           tctxt->document = xsltFindDocument(tctxt, ctxt->context->doc);
-           if (tctxt->document == NULL)
-               tctxt->document = oldDocumentPtr;
-           else
-               tctxt->xpathCtxt->doc = ctxt->context->doc;
+                   (tctxt->document->doc != ctxt->context->doc)) {
+           /*
+            * The xpath context document needs to be changed.  If the
+            * current context document is a node-set, we must use an
+            * xsltDocument associated with the node-set, which may or
+            * may not currently exist.
+            */
+           if (xmlStrEqual((const xmlChar *)ctxt->context->doc->name,
+                       BAD_CAST " fake node libxslt")) {       /* node-set */
+               /*
+                * Check whether we already have an xsltDocument set up
+                */
+               if (ctxt->context->doc->_private == NULL)       /* nope */
+                   ctxt->context->doc->_private =
+                       xsltNewDocument(tctxt, ctxt->context->doc);
+               tctxt->document = ctxt->context->doc->_private;
+           }
+           else {
+               tctxt->document = xsltFindDocument(tctxt, ctxt->context->doc);
+               if (tctxt->document == NULL)
+                   tctxt->document = oldDocumentPtr;
+               else
+                   tctxt->xpathCtxt->doc = ctxt->context->doc;
+           }
        }
        nodelist = xsltGetKey(tctxt, key, keyURI, value);
        tctxt->document = oldDocumentPtr;
index 4be9ee7..35b6e2b 100644 (file)
@@ -1815,6 +1815,10 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
                    xmlXPathFreeObject(elem->value);
                }
                next = (xmlDocPtr) tmp->next;
+               if (tmp->_private != NULL) {
+                   xsltFreeDocumentKeys(tmp->_private);
+                   xmlFree(tmp->_private);
+               }
                xmlFreeDoc(tmp);
                tmp = next;
            }
@@ -3108,7 +3112,7 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
     int nbsorts = 0;
     xmlNodePtr sorts[XSLT_MAX_SORT];
     xmlDocPtr oldXDocPtr;
-    xsltDocumentPtr oldCDocPtr, tmpDocPtr, newDocPtr = NULL;
+    xsltDocumentPtr oldCDocPtr, newDocPtr = NULL;
     xmlNodePtr newDocPtrPtr = NULL;
     int oldNsNr;
     xmlNsPtr *oldNamespaces;
@@ -3376,10 +3380,6 @@ error:
          If we created a "pseudo-document" we must free it now
        */
        if (newDocPtr != NULL) {
-           tmpDocPtr = (xsltDocumentPtr)&ctxt->docList;
-           while (tmpDocPtr->next != newDocPtr)
-               tmpDocPtr = tmpDocPtr->next;
-           tmpDocPtr->next = newDocPtr->next;
            newDocPtr->doc->parent = NULL;
            xsltFreeDocumentKeys(newDocPtr);
            xmlFree(newDocPtr);
index 6cb2986..00b07b9 100644 (file)
@@ -29,6 +29,7 @@
 #include "transform.h"
 #include "imports.h"
 #include "preproc.h"
+#include "keys.h"
 
 #ifdef WITH_XSLT_DEBUG
 #define WITH_XSLT_DEBUG_VARIABLE
@@ -128,12 +129,20 @@ xsltFreeRVTs(xsltTransformContextPtr ctxt)
     cur = ctxt->tmpRVT;
     while (cur != NULL) {
         next = (xmlDocPtr) cur->next;
+       if (cur->_private != NULL) {
+           xsltFreeDocumentKeys(cur->_private);
+           xmlFree(cur->_private);
+       }
        xmlFreeDoc(cur);
        cur = next;
     }
     cur = ctxt->persistRVT;
     while (cur != NULL) {
         next = (xmlDocPtr) cur->next;
+       if (cur->_private != NULL) {
+           xsltFreeDocumentKeys(cur->_private);
+           xmlFree(cur->_private);
+       }
        xmlFreeDoc(cur);
        cur = next;
     }
index 7a1f612..39decd9 100644 (file)
@@ -10,6 +10,7 @@ EXTRA_DIST =                                          \
        node-set.4.xml node-set.4.xsl node-set.4.out    \
        node-set.5.xml node-set.5.xsl node-set.5.out    \
        node-set.6.xml node-set.6.xsl node-set.6.out    \
+       node-set.7.xml node-set.7.xsl node-set.7.out    \
        object-type.1.xml object-type.1.xsl object-type.1.out \
        import-test1a.imp import-test1b.imp import-test1.out \
        import-test1.xml import-test1.xsl
diff --git a/tests/exslt/common/node-set.7.out b/tests/exslt/common/node-set.7.out
new file mode 100644 (file)
index 0000000..dfb17cf
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+A
diff --git a/tests/exslt/common/node-set.7.xml b/tests/exslt/common/node-set.7.xml
new file mode 100644 (file)
index 0000000..8eb294b
--- /dev/null
@@ -0,0 +1 @@
+<root>junk</root>
diff --git a/tests/exslt/common/node-set.7.xsl b/tests/exslt/common/node-set.7.xsl
new file mode 100644 (file)
index 0000000..7f1068e
--- /dev/null
@@ -0,0 +1,28 @@
+<xsl:transform
+  version="1.0"
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:exsl="http://exslt.org/common"
+  extension-element-prefixes="exsl">
+
+  <xsl:key name="k" match="a" use="@x"/>
+
+  <xsl:template match="/">
+    <xsl:variable name="v">
+      <n>
+        <a x="1" y="A"/>
+        <a x="2" y="B"/>
+      </n>
+    </xsl:variable>
+    <xsl:apply-templates select="exsl:node-set($v)/*"/>
+  </xsl:template>
+
+  <xsl:template match="n">
+<!--    <xsl:apply-templates select="a[@x='1']"/> -->
+    <xsl:apply-templates select="key('k','1')"/>
+  </xsl:template>
+
+  <xsl:template match="a">
+    <xsl:value-of select="@y"/>
+  </xsl:template>
+
+</xsl:transform>