[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

xpath confusion (compound xpath)

Subject: xpath confusion (compound xpath)
From: S Woodside <sbwoodside@xxxxxxxxx>
Date: Sat, 18 Jan 2003 15:40:37 -0500
xsl if compound
I have the following source XML. If you're familiar with relax NG you 'll see that it's an RNG grammar.

<grammar>
  <start>
    <element>
      [...]
      <zeroOrMore>
        <choice>
          <!-- interesting part (1) starts here -->
          <element name="objective">
            <optional>
              <attribute name="id">
                <data type="ID" />
              </attribute>
            </optional>
            <oneOrMore>
              <element name="para">
                <zeroOrMore>
                  <text />
                </zeroOrMore>
              </element>
            </oneOrMore>
          </element>
          <!-- interesting part ends here -->
        [...]
        </choice>
      [...]
    </element>
    [...]
  </start>
</grammar>

The Xpath to the subtree (1) that I'm interested in is
/grammar/start/element/zeroOrMore/choice/element[1] (call this (2))

What I wish to do is to apply templates to the subtree (1) where I will determine if there is a "zeroOrMore" node between the XPath (2) and the context node. However I'm having major trouble, I can't figure out how to make it work. Here's a simple test XSLT test.xsl that has the xpath (2) hardcoded into it for testing purposes.


<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'> <xsl:output method="text"/> <xsl:strip-space elements="*"/>

<xsl:template match="/">
<xsl:apply-templates select="/grammar/start/element/zeroOrMore/choice/element[1]"/>
</xsl:template>


<xsl:template match="/grammar/start/element/zeroOrMore/choice/element[1]">
<xsl:call-template name="testit"/>
</xsl:template>
<xsl:template match="/grammar/start/element/zeroOrMore/choice/element[1]//*">
<xsl:call-template name="testit"/>
</xsl:template>


<xsl:template name="testit">
<xsl:choose>
<xsl:when
test="/grammar/start/element/zeroOrMore/choice/element[1]//zeroOrMore// *[self=current()]">
<xsl:call-template name="thepath"/>
<xsl:text> YES</xsl:text>
<xsl:text>&#xA;</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="thepath"/>
<xsl:text> NO</xsl:text>
<xsl:text>&#xA;</xsl:text>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>


<!-- see "thepath" template at the end of the email, it's code from the list -->
</xsl:stylesheet>


Here's the output from sablotron:

[simons-tibook:~/Sites/AxkitSite] woodside% sabcmd test.xsl form.html
/grammar/start/element/zeroOrMore/choice/element[1] NO
/grammar/start/element/zeroOrMore/choice/element[1]/optional NO
/grammar/start/element/zeroOrMore/choice/element[1]/optional/attribute NO
/grammar/start/element/zeroOrMore/choice/element[1]/optional/attribute/ data NO
/grammar/start/element/zeroOrMore/choice/element[1]/oneOrMore NO
/grammar/start/element/zeroOrMore/choice/element[1]/oneOrMore/element NO
/grammar/start/element/zeroOrMore/choice/element[1]/oneOrMore/element/ zeroOrMore NO
/grammar/start/element/zeroOrMore/choice/element[1]/oneOrMore/element/ zeroOrMore/text NO


It's all right, except for the last one, which should be a YES.

Here's the even stranger output from xsltproc:

[simons-tibook:~/Sites/AxkitSite] woodside% xsltproc test.xsl form.html
/grammar/start/element/zeroOrMore/choice/element[1] NO
/grammar/start/element/zeroOrMore/choice/element[1]/optional NO
/grammar/start/element/zeroOrMore/choice/element[1]/optional/attribute NO
/grammar/start/element/zeroOrMore/choice/element[1]/optional/attribute/ data NO
/grammar/start/element/zeroOrMore/choice/element[1]/oneOrMore/element NO


(Why did xsltproc stop there???)

What am I doing wrong?

Simon


------


The "testit" template

<xsl:template name="thepath">
<xsl:variable name="theResult">
<xsl:variable name="theNode" select="."/>
<xsl:for-each select="$theNode | $theNode/ancestor-or-self::node()[..]">
<xsl:element name="slash">/</xsl:element>
<xsl:choose>
<xsl:when test="self::*">
<xsl:element name="nodeName">
<xsl:value-of select="name()"/>
<xsl:variable name="thisPosition"
select="count(preceding-sibling::*[name(current()) = name()])"/>
<xsl:variable name="numFollowing"
select="count(following-sibling::*[name(current()) = name()])"/>
<xsl:if test="$thisPosition + $numFollowing > 0">
<xsl:value-of select="concat('[', $thisPosition + 1, ']')"/>
</xsl:if>
</xsl:element>
</xsl:when>
<xsl:otherwise> <!-- This node is not an element -->
<xsl:choose>
<xsl:when test="count(. | ../@*) = count(../@*)">
<!-- Attribute -->
<xsl:element name="nodeName">
<xsl:value-of select="concat('@',name())"/>
</xsl:element>
</xsl:when>
<xsl:when test="self::text()">
<!-- Text -->
<xsl:element name="nodeName">
<xsl:value-of select="'text()'"/>
<xsl:variable name="thisPosition"
select="count(preceding-sibling::text())"/>
<xsl:variable name="numFollowing"
select="count(following-sibling::text())"/>
<xsl:if test="$thisPosition + $numFollowing > 0">
<xsl:value-of select="concat('[', $thisPosition + 1, ']')"/>
</xsl:if>
</xsl:element>
</xsl:when>
<xsl:when test="self::processing-instruction()">
<!-- Processing Instruction -->
<xsl:element name="nodeName">
<xsl:value-of select="'processing-instruction()'"/>
<xsl:variable name="thisPosition"
select="count(preceding-sibling::processing-instruction())"/>
<xsl:variable name="numFollowing"
select="count(following-sibling::processing-instruction())"/>
<xsl:if test="$thisPosition + $numFollowing > 0">
<xsl:value-of select="concat('[', $thisPosition + 1, ']')"/>
</xsl:if>
</xsl:element>
</xsl:when>
<xsl:when test="self::comment()">
<!-- Comment -->
<xsl:element name="nodeName">
<xsl:value-of select="'comment()'"/>
<xsl:variable name="thisPosition"
select="count(preceding-sibling::comment())"/>
<xsl:variable name="numFollowing"
select="count(following-sibling::comment())"/>
<xsl:if test="$thisPosition + $numFollowing > 0">
<xsl:value-of select="concat('[', $thisPosition + 1, ']')"/>
</xsl:if>
</xsl:element>
</xsl:when>
<xsl:when test="count(. | ../namespace::*) = count(../namespace::*)">
<!-- Namespace: -->
<xsl:variable name="apos">'</xsl:variable>
<xsl:element name="nodeName">
<xsl:value-of select="concat('namespace::*',
'[local-name() = ', $apos, local-name(), $apos, ']')"/>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="$theResult"/>
</xsl:template>
---
www.simonwoodside.com



XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.