enhanced xsltInitCtxtKey to take care of multiple instances of a key with
authorWilliam M. Brack <wbrack@src.gnome.org>
Mon, 18 Aug 2003 06:50:15 +0000 (06:50 +0000)
committerWilliam M. Brack <wbrack@src.gnome.org>
Mon, 18 Aug 2003 06:50:15 +0000 (06:50 +0000)
* 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).

ChangeLog
libxslt/keys.c
tests/docs/Makefile.am
tests/docs/bug-128.xml [new file with mode: 0644]
tests/general/Makefile.am
tests/general/bug-128.out [new file with mode: 0644]
tests/general/bug-128.xsl [new file with mode: 0644]

index 67335c9..35edb81 100644 (file)
--- 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
index 4178c1c..f3a1f63 100644 (file)
@@ -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;
index 873b4b1..cf40b49 100644 (file)
@@ -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 (file)
index 0000000..0a3027d
--- /dev/null
@@ -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>
+
index a37d449..300235a 100644 (file)
@@ -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 (file)
index 0000000..31a5e2e
--- /dev/null
@@ -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 (file)
index 0000000..0a3027d
--- /dev/null
@@ -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>
+