summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--libxslt/keys.c30
-rw-r--r--tests/docs/Makefile.am1
-rw-r--r--tests/docs/bug-128.xml26
-rw-r--r--tests/general/Makefile.am1
-rw-r--r--tests/general/bug-128.out5
-rw-r--r--tests/general/bug-128.xsl26
7 files changed, 90 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 67335c95..35edb810 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Mod Aug 18 14:42:12 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+ * keys.c: enhanced xsltInitCtxtKey to take care of multiple
+ instances of a key with the same namespace:name, reported
+ on the mailing list by Ian Young. Added regression test
+ (bug-128).
+
Thu Aug 15 13:00:02 HKT 2003 William Brack <wbrack@mmm.com.hk>
* variables.c: fixed bug 119699 (missing error on shadowed
diff --git a/libxslt/keys.c b/libxslt/keys.c
index 4178c1c1..f3a1f63a 100644
--- a/libxslt/keys.c
+++ b/libxslt/keys.c
@@ -519,9 +519,30 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr doc,
if ((nodelist == NULL) || (nodelist->nodeNr <= 0))
goto error;
- table = xsltNewKeyTable(keyd->name, keyd->nameURI);
- if (table == NULL)
- goto error;
+ /**
+ * Multiple key definitions for the same name are allowed, so
+ * we must check if the key is already present for this doc
+ */
+ table = (xsltKeyTablePtr) doc->keys;
+ while (table != NULL) {
+ if (xmlStrEqual(table->name, keyd->name) &&
+ (((keyd->nameURI == NULL) && (table->nameURI == NULL)) ||
+ ((keyd->nameURI != NULL) && (table->nameURI != NULL) &&
+ (xmlStrEqual(table->nameURI, keyd->nameURI)))))
+ break;
+ table = table->next;
+ }
+ /**
+ * If the key was not previously defined, create it now and
+ * chain it to the list of keys for the doc
+ */
+ if (table == NULL) {
+ table = xsltNewKeyTable(keyd->name, keyd->nameURI);
+ if (table == NULL)
+ goto error;
+ table->next = doc->keys;
+ doc->keys = table;
+ }
for (i = 0;i < nodelist->nodeNr;i++) {
if (IS_XSLT_REAL_NODE(nodelist->nodeTab[i])) {
@@ -560,9 +581,6 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr doc,
}
}
- table->next = doc->keys;
- doc->keys = table;
-
error:
ctxt->document = oldDoc;
ctxt->xpathCtxt->doc = oldXDoc;
diff --git a/tests/docs/Makefile.am b/tests/docs/Makefile.am
index 873b4b10..cf40b497 100644
--- a/tests/docs/Makefile.am
+++ b/tests/docs/Makefile.am
@@ -127,6 +127,7 @@ EXTRA_DIST = \
bug-125.xml \
bug-126.xml \
bug-127.xml \
+ bug-128.xml \
character.xml \
array.xml \
items.xml
diff --git a/tests/docs/bug-128.xml b/tests/docs/bug-128.xml
new file mode 100644
index 00000000..0a3027d2
--- /dev/null
+++ b/tests/docs/bug-128.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:test="http://www.example.org/test">
+ <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
+
+ <xsl:key name="k" match="test:a" use="@a"/>
+ <xsl:key name="k" match="test:b" use="@b"/>
+ <xsl:key name="k" match="test.a" use="@a"/>
+
+ <xsl:template match="/">
+ <test:data>
+ <xsl:for-each select="key('k','1')">
+ <xsl:copy-of select="."/>
+ </xsl:for-each>
+ </test:data>
+ </xsl:template>
+
+ <xsl:template match="text()|@*"/>
+
+ <test:data>
+ <test:a a="1"/>
+ <test:b b="1"/>
+ </test:data>
+</xsl:stylesheet>
+
diff --git a/tests/general/Makefile.am b/tests/general/Makefile.am
index a37d4495..300235af 100644
--- a/tests/general/Makefile.am
+++ b/tests/general/Makefile.am
@@ -132,6 +132,7 @@ EXTRA_DIST = \
bug-125.out bug-125.xsl \
bug-126.out bug-126.xsl \
bug-127.out bug-127.xsl \
+ bug-128.out bug-128.xsl \
character.out character.xsl \
character2.out character2.xsl \
itemschoose.out itemschoose.xsl \
diff --git a/tests/general/bug-128.out b/tests/general/bug-128.out
new file mode 100644
index 00000000..31a5e2e9
--- /dev/null
+++ b/tests/general/bug-128.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<test:data xmlns:test="http://www.example.org/test">
+ <test:a a="1"/>
+ <test:b b="1"/>
+</test:data>
diff --git a/tests/general/bug-128.xsl b/tests/general/bug-128.xsl
new file mode 100644
index 00000000..0a3027d2
--- /dev/null
+++ b/tests/general/bug-128.xsl
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:test="http://www.example.org/test">
+ <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
+
+ <xsl:key name="k" match="test:a" use="@a"/>
+ <xsl:key name="k" match="test:b" use="@b"/>
+ <xsl:key name="k" match="test.a" use="@a"/>
+
+ <xsl:template match="/">
+ <test:data>
+ <xsl:for-each select="key('k','1')">
+ <xsl:copy-of select="."/>
+ </xsl:for-each>
+ </test:data>
+ </xsl:template>
+
+ <xsl:template match="text()|@*"/>
+
+ <test:data>
+ <test:a a="1"/>
+ <test:b b="1"/>
+ </test:data>
+</xsl:stylesheet>
+