+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
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);
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;
xmlXPathFreeObject(elem->value);
}
next = (xmlDocPtr) tmp->next;
+ if (tmp->_private != NULL) {
+ xsltFreeDocumentKeys(tmp->_private);
+ xmlFree(tmp->_private);
+ }
xmlFreeDoc(tmp);
tmp = next;
}
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;
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);
#include "transform.h"
#include "imports.h"
#include "preproc.h"
+#include "keys.h"
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_VARIABLE
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;
}
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
--- /dev/null
+<?xml version="1.0"?>
+A
--- /dev/null
+<root>junk</root>
--- /dev/null
+<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>