Menu

Is '//' and 'descendant-or-self' not the same

Help
2004-07-15
2012-10-08
  • Martin Beck

    Martin Beck - 2004-07-15

    Hello,

    with Saxon 8.0b the following query's results different values. Why?

    <xsl:value-of select="/root/descendant-or-self::test[5]/@title" />

    <xsl:value-of select="/root//test[5]/@title" />

    The input document:

    <?xml version="1.0" encoding="iso-8859-1"?>

    <root>

        <test title="test1" />
       
        <test title="test2" />
       
        <container>
            <test title="test3" />
        </container>
       
        <container>
            <test title="test4" />
        </container>
       
        <test title="test5" />
       
       
        <test title="test6" />
       
       
        <test title="test7" />

    </root>

    The Stylesheet:

    <?xml version="1.0" encoding="iso-8859-1"?>

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="text" encoding="iso-8859-1" />   

        <xsl:template match="/">
       
            <xsl:for-each select="/root//test">
                <xsl:value-of select="position()" />
                <xsl:text> </xsl:text>
                <xsl:value-of select="@title" /><xsl:text>&#x0A;</xsl:text>
                </xsl:for-each>
       
            <xsl:text>&#x0A;</xsl:text>
            <xsl:text>&#x0A;</xsl:text>
           
            <xsl:text>Why is the result of this two XPATH-Querys different? Is '//' not equal 'descendant-or-self::' ?</xsl:text>
            <xsl:text>&#x0A;</xsl:text>
            <xsl:value-of select="/root/descendant-or-self::test[5]/@title" />
            <xsl:text>&#x0A;</xsl:text>
            <xsl:value-of select="/root//test[5]/@title" />
       
        </xsl:template>
       
       

    </xsl:stylesheet>

    Thanks for help.

    Martin

     
    • Michael Kay

      Michael Kay - 2004-07-15

      This is a basic XPath coding question and doesn't really belong on the Saxon list.

      //a[5] means /descendant-or-self::node/a[5], and selects every a element that is the fifth child of its parent.

      /descendant-or-self::a[5] selects the fifth a element that is a descendant (or self) of the root node.

      Michael Kay

       
  • Stefan_E

    Stefan_E - 2012-09-16

    Sorry for reviving such an old thread: Whilst I can see the logic in above
    example, I still get confused on my example... hmm (using Saxon 9.4.0.3
    through Oxygen)

    My document looks something like this (graphml file to be processed with yed):

    <root>
    <node isLeaf="Y"/>
    <node isLeaf="N">
    <graph>
    <node isLeaf="Y"/>
    <node/>
    </graph>
    </node>
    <node isLeaf="N">
    <graph/>
    </node>
    <node isLeaf="N">
    <graph>
    <node isLeaf="Y"/>
    </graph>
    </node>
    </root>

    I don't want remove the node which doesn't have a leaf node <node isLeave="Y">
    So, I'm using an xsl template as follows:

    <xsl:template match="node">
    <xsl:if test="descendant-or-self::node">
    <node>
    <xsl:apply-templates select="@*|node()"/>
    </node>
    </xsl:if>
    </xsl:template>

    which works.

    But using

    <xsl:if test="//node">

    copies everything ...How does the predicate get matched?

    Thanks for help,
    Stefan

     
  • Stefan_E

    Stefan_E - 2012-09-16

    "I don't want remove" --> I want remove ... :-)

     
  • Markus Abt

    Markus Abt - 2012-09-16

    No, "//" is not the same as "descendant-or-self".
    Neither is "descendant-or-self::node" the same as "//node".

    "//" is the same as "/descendant-or-self::node()/".

    Therefore, "//node" is the same as "/descendant-or-self::node()/child::node"
    Which is in two aspects different from "descendant-or-self::node":
    1. the former starts at the root node "/", the latter doesn't.
    2. Note the additional step on the child axis in the former.

    Regards,
    Markus