Re: [xslt] xsl:key pattern bug?



On Tue, Jan 29, 2002 at 04:15:52PM -0800, Bob Stayton wrote:
> I've run into an odd little problem that I think is
> an xsltproc bug, or it could be my misunderstanding of xsl:key's
> 'match' attribute.  It appears that the '|' union operator
> in the xsl:key match attribute isn't always handled correctly.

  More precisely it's nearly always handled incorrectly.
The XPath selection expression generated from the match was improper in
case of unions.
  Your expression was transformed as "//div|obj" (or "//obj|div")
instead of "//div|//obj" . The enclosed patch fixes it.

   thanks for the report,

Daniel

-- 
Daniel Veillard      | Red Hat Network https://rhn.redhat.com/
veillard@redhat.com  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/
Index: libxslt/keys.c
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/keys.c,v
retrieving revision 1.23
diff -u -r1.23 keys.c
--- libxslt/keys.c	2001/08/14 16:46:18	1.23
+++ libxslt/keys.c	2002/01/30 11:37:21
@@ -236,6 +236,7 @@
 	   const xmlChar *use, xmlNodePtr inst) {
     xsltKeyDefPtr key;
     xmlChar *pattern = NULL;
+    int current, end, start;
 
     if ((style == NULL) || (name == NULL) || (match == NULL) || (use == NULL))
 	return(-1);
@@ -250,12 +251,48 @@
     key->use = xmlStrdup(use);
     key->inst = inst;
 
-    if (key->match[0] != '/') {
-	pattern = xmlStrdup((xmlChar *)"//");
-	pattern = xmlStrcat(pattern, key->match);
-    } else {
-	pattern = xmlStrdup(key->match);
+    /*
+     * Split the | and register it as as many keys
+     */
+    current = end = 0;
+    while (match[current] != 0) {
+	start = current;
+	while (IS_BLANK(match[current]))
+	    current++;
+	end = current;
+	while ((match[end] != 0) && (match[end] != '|')) {
+	    end++;
+	}
+	if (current == end) {
+	    xsltPrintErrorContext(NULL, style, inst);
+	    xsltGenericError(xsltGenericErrorContext,
+			     "key pattern is empty\n");
+	    style->errors++;
+	    goto error;
+	}
+	if (match[start] != '/') {
+	    pattern = xmlStrcat(pattern, (xmlChar *)"//");
+	    if (pattern == NULL) {
+		style->errors++;
+		goto error;
+	    }
+	}
+	pattern = xmlStrncat(pattern, &match[start], end - start);
+	if (pattern == NULL) {
+	    style->errors++;
+	    goto error;
+	}
+
+	if (match[end] == '|') {
+	    pattern = xmlStrcat(pattern, (xmlChar *)"|");
+	    end++;
+	}
+	current = end;
     }
+#ifdef WITH_XSLT_DEBUG_KEYS
+    xsltGenericDebug(xsltGenericDebugContext,
+	"   resulting pattern %s\n", pattern);
+#endif
     key->comp = xmlXPathCompile(pattern);
     if (key->comp == NULL) {
 	xsltPrintErrorContext(NULL, style, inst);
@@ -274,6 +311,7 @@
     }
     key->next = style->keys;
     style->keys = key;
+error:
     if (pattern != NULL)
 	xmlFree(pattern);
     return(0);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]