[xslt] xsltCompileStepPattern problem



I have two problems, one I have a solution for and the other I am
stumped.
First, libxslt doesn't handle wildcard child patterns (child::*); the
attached patch fixes that. The second problem is with predicates. Given
a templete with the match pattern:
//b/child::*[self::aa or self::bb or self::cc][position()=last()]
the stylesheet should get the last aa, bb, or cc element with element b
as a parent but it doesn't. In fact I tested this with testXPath and it
works.
$ gnome/gnome-xml/testXPath -i abc.xml "//b/child::*[self::aa or
self::bb or self::cc][position()=last()]"
Object is a Node Set :
Set contains 3 nodes:
1  ELEMENT cc
2  ELEMENT cc
3  ELEMENT aa

I also tested with xt and it works. I suspect the precompiled pattern
gets missinterpreted as get the aa, bb, or cc element if it is the last
element in the context of element b; but I don't really know.

attached are sample xml, xsl, and patch for pattern.c

Charlie B.

<?xml version="1.0"?>
<a>
  <b>
    <aa>first</aa>
    <bb>second</bb>
    <cc>third</cc>
    <d>d</d>
    <e>e</e>
  </b>
  <b>
    <cc>first</cc>
    <e>e</e>
  </b>
  <b>
    <bb>first</bb>
    <aa>second</aa>
    <d>d</d>
    <d>d</d>
  </b>
</a>



<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version='1.0'>

<xsl:output method="xml"
            indent="yes"/>

<!-- ==================================================================== -->

<!-- ********************************************************************
     a default template rule to match any elements that are not covered 
     by other templates
     ******************************************************************** -->
     <!--
<xsl:template match="@*|node()|comment()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()|comment()"/>
  </xsl:copy>
</xsl:template>
-->

<!--
-->
<xsl:template match="//b/child::*[self::aa or self::bb or self::cc][position()=last()]">
  <xsl:variable name="pos" select="position()"/>
  <xsl:message>
    <xsl:text>found=</xsl:text>
    <xsl:value-of select="$pos"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="position()"/>
  </xsl:message>
  <xsl:if test="position()=1">
    <xsl:message>
      <xsl:text>found=</xsl:text>
      <xsl:value-of select="name(.)"/>
    </xsl:message>
  </xsl:if>
  <xsl:if test="position()=last()">
    <xsl:message>
      <xsl:text>found last</xsl:text>
    </xsl:message>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

Index: pattern.c
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/pattern.c,v
retrieving revision 1.49
diff -c -r1.49 pattern.c
*** pattern.c	2002/01/17 22:40:39	1.49
--- pattern.c	2002/01/30 03:35:48
***************
*** 1272,1282 ****
  		xmlFree(token);
  		token = xsltScanName(ctxt);
  		if (token == NULL) {
! 		    xsltPrintErrorContext(NULL, NULL, NULL); /* TODO */
! 		    xsltGenericError(xsltGenericErrorContext,
  			    "xsltCompileStepPattern : QName expected\n");
! 		    ctxt->error = 1;
! 		    goto error;
  		}
  		URI = xsltGetQNameURI(ctxt->elem, &token);
  		if (token == NULL) {
--- 1272,1288 ----
  		xmlFree(token);
  		token = xsltScanName(ctxt);
  		if (token == NULL) {
! 	            if (CUR == '*') {
!             	        NEXT;
! 	                PUSH(XSLT_OP_ALL, token, NULL);
! 	                goto parse_predicate;
! 	            } else {
! 		        xsltPrintErrorContext(NULL, NULL, NULL); /* TODO */
! 		        xsltGenericError(xsltGenericErrorContext,
  			    "xsltCompileStepPattern : QName expected\n");
! 		        ctxt->error = 1;
! 		        goto error;
! 		    }
  		}
  		URI = xsltGetQNameURI(ctxt->elem, &token);
  		if (token == NULL) {


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