Concept XML XLST preceding-sibling and ancestor

前端 未结 3 1989
滥情空心
滥情空心 2020-12-23 21:38

I am very new to xslt, and found it can be easy or complex. I want to make clear some concepts. What is preceding-sibling and what is ancestor, after searching from google,

相关标签:
3条回答
  • 2020-12-23 21:43

    Preceding-sibling gets all element siblings that preceded it in the current node level. Unless you specify one or more of those preceding siblings with an xpath expression. If you specify a specific preceding-sibling with xpath it always starts with 1 in square brackets.

    Ancestor is the first matching ancestor that matches the expression. So it goes back up the node tree to look at a matching expression based on where you currently are pointing. So if you were at product/inventory/drink/pop or just /pop then ancestor inventory/totalprice just looks for the frist occurence and it should only return back a pointer to point to that matching case else it will be pointing to nothing and you'll still be pointing at pop.

    0 讨论(0)
  • 2020-12-23 21:59

    The preceding-sibling:: axis

    The preceding-sibling:: axis is an axis of navigation that includes all the preceding sibling elements to the focus element. By "sibling" we mean a different element which has the same parent to the reference item. By "preceding" we mean a node that occurs before the reference one. The order of the preceding-sibling axis is the reverse document order. Take a look at this document:

    <fruit>
      <banana>
       <lady-finger-banana/>
      </banana> 
      <apple/>
      <pear/>
      <kiwi/>
    </fruit>
    

    If the focus node is pear, then the sequence preceding-sibling::* is ...

    1. apple
    2. banana

    Note: fruit, pear, lady-finger-banana and kiwi are not in the sequence.

    So the following is true:

    • preceding-sibling::*[ 1] is the apple
    • preceding-sibling::*[ 2] is the banana
    • count( preceding-sibling::*) is 2
    • preceding-sibling::apple[ 1] is also the apple
    • preceding-sibling::banana[ 1] is the banana
    • preceding-sibling::*[ 3] is absent or the empty sequence

    preceding-sibling::pop/ancestor::inventory/totalprice Example

    We have to alter your sample document a little bit to usefully study this example

    <product>
        <inventory>
            <drink>
                <lemonade>
                    <price>$2.50</price>
                    <amount>20</amount>
                </lemonade>
                <pop>
                    <price>$1.50</price>
                    <amount>10</amount>
                </pop>
                <focus-item />
             </drink>
            <totalprice>$15</totalprice>  
        </inventory>
    </product>
    

    Let us say the focus is on the element focus-item. To evaluate the expression preceding-sibling::pop/ancestor::inventory/totalprice follow these steps:

    1. preceding-sibling::pop selects all the preceding pop elements to focus-item. This evaluates to a sequence of one node.
    2. For each item in the left hand sequence (just one pop element it so happens), set this item as a temporary focus item, and evaluate the expression of the right of the / operator which is ...

      ancestor::inventory
      

      There is only one such node, which is the ancestral inventory node. Thus the first / operator evaluates to a sequence of one inventory node.

    3. Now we evaluate the effect of the second / and its right-hand operand expression total price. For each item in the left hand sequence (just one inventory node so it happens), set this as a temporary focus item and evaluate totalprice.

    4. totalprice is short for child::totalprice. There is only one total price element on the child axis of the temporary focus node, so the final result is a sequence of one node, which is the total price node.

    Understanding by Diagrams

    Here is a diagram for preceding-sibling::. In it the reference node is Charlie and the node on the preceding-sibling:: axis is in green. It is the only such node.

    enter image description here

    0 讨论(0)
  • 2020-12-23 22:02

    Axes useful for navigation through the node tree. So it depends from your problem what kind of axis is useful.

    The following stylesheet illustrates the difference.

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0">
       <xsl:output method="xml" indent="yes"/>
    
       <xsl:template match="snack">
            <xsl:variable name="siblings" select="ancestor::node()"/>
            <debug>
            <xsl:for-each select="preceding-sibling::node()">
                    <sibling>
                            <xsl:value-of select="local-name()"/>
                    </sibling>
            </xsl:for-each>
            <xsl:for-each select="ancestor::node()">
                    <ancestor>
                            <xsl:value-of select="local-name()"/>
                    </ancestor>
            </xsl:for-each>
    
            </debug>
       </xsl:template>
    
       <xsl:template match="*">
             <xsl:apply-templates select="*"/>
       </xsl:template>
    </xsl:stylesheet>
    
    0 讨论(0)
提交回复
热议问题