diff options
author | William M. Brack <wbrack@src.gnome.org> | 2004-08-02 15:51:00 +0000 |
---|---|---|
committer | William M. Brack <wbrack@src.gnome.org> | 2004-08-02 15:51:00 +0000 |
commit | 58e98329ecf9ec88bdc04349a2c7bc64a220df63 (patch) | |
tree | df32208dcb3b6471f2d5c89d6add8ee6402709e0 | |
parent | 391aed81b51dbad8608773e4c1f65fd917beb917 (diff) | |
download | libxslt-58e98329ecf9ec88bdc04349a2c7bc64a220df63.tar.gz libxslt-58e98329ecf9ec88bdc04349a2c7bc64a220df63.tar.bz2 libxslt-58e98329ecf9ec88bdc04349a2c7bc64a220df63.zip |
added code to assure keys are generated when needed for node-sets (bug
* 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.
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | libxslt/documents.c | 6 | ||||
-rw-r--r-- | libxslt/functions.c | 30 | ||||
-rw-r--r-- | libxslt/transform.c | 10 | ||||
-rw-r--r-- | libxslt/variables.c | 9 | ||||
-rw-r--r-- | tests/exslt/common/Makefile.am | 1 | ||||
-rw-r--r-- | tests/exslt/common/node-set.7.out | 2 | ||||
-rw-r--r-- | tests/exslt/common/node-set.7.xml | 1 | ||||
-rw-r--r-- | tests/exslt/common/node-set.7.xsl | 28 |
9 files changed, 81 insertions, 13 deletions
@@ -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 diff --git a/libxslt/documents.c b/libxslt/documents.c index c4e4b363..a30374ab 100644 --- a/libxslt/documents.c +++ b/libxslt/documents.c @@ -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); diff --git a/libxslt/functions.c b/libxslt/functions.c index ad839cc4..aa1a236d 100644 --- a/libxslt/functions.c +++ b/libxslt/functions.c @@ -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; diff --git a/libxslt/transform.c b/libxslt/transform.c index 4be9ee7d..35b6e2b1 100644 --- a/libxslt/transform.c +++ b/libxslt/transform.c @@ -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); diff --git a/libxslt/variables.c b/libxslt/variables.c index 6cb29868..00b07b92 100644 --- a/libxslt/variables.c +++ b/libxslt/variables.c @@ -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; } diff --git a/tests/exslt/common/Makefile.am b/tests/exslt/common/Makefile.am index 7a1f6126..39decd98 100644 --- a/tests/exslt/common/Makefile.am +++ b/tests/exslt/common/Makefile.am @@ -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 index 00000000..dfb17cf5 --- /dev/null +++ b/tests/exslt/common/node-set.7.out @@ -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 index 00000000..8eb294b5 --- /dev/null +++ b/tests/exslt/common/node-set.7.xml @@ -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 index 00000000..7f1068ec --- /dev/null +++ b/tests/exslt/common/node-set.7.xsl @@ -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> |