概念XML XLST前兄弟和祖先

olo*_*olo 27 xml xslt xpath

我对xslt很新,发现它很简单或很复杂.我想澄清一些概念.什么是前兄弟和什么是祖先,从谷歌搜索后,我找到了祖先的解释.并且他们网站上的图表更容易理解.

但我仍然不明白兄弟姐妹

<product>
    <inventory>
        <drink>
            <lemonade>
                <price>$2.50</price>
                <amount>20</amount>
            </lemonade>
            <pop>
                <price>$1.50</price>
                <amount>10</amount>
            </pop>
        </drink>
          <service>
           <address />
            <phone />
            <delivery> City </delivery>
          </service>      
        <snack>
            <chips>
                <price>$4.50</price>
                <amount>60</amount>
            </chips>
        </snack>
        <hotfood></hotfood>
         <totalprice> $15</totleprice>

    </inventory>
</product>
Run Code Online (Sandbox Code Playgroud)

那我怎么读这个前兄弟:: pop/ancestor :: inventory/totalprice

祖先:: inventory/totalprice = product\inventory\totalprice previous-sibling :: pop - 我不明白这个如何一起阅读?

非常感谢

Sea*_*kin 70

previous-sibling :: axis

previous-sibling :: axis是一个导航轴,包含焦点元素的所有前面的兄弟元素."兄弟姐妹"是指与参考物品具有相同父母的不同元素."前面"是指在引用之前出现的节点.前一个兄弟轴的顺序是反向文档顺序.看看这个文件:

<fruit>
  <banana>
   <lady-finger-banana/>
  </banana> 
  <apple/>
  <pear/>
  <kiwi/>
</fruit>
Run Code Online (Sandbox Code Playgroud)

如果焦点节点是梨,那么前面的sibling ::*序列是......

  1. 苹果
  2. 香蕉

注意:水果,梨,女士手指香蕉和猕猴桃不在序列中.

所以以下是真的:

  1. previous-sibling ::*[1]是苹果
  2. 前兄弟::*[2]是香蕉
  3. count(preceding-sibling ::*)是2
  4. previous-sibling :: apple [1]也是苹果
  5. previous-sibling :: banana [1]是香蕉
  6. previous-sibling ::*[3]不存在或空序列

previous-sibling :: pop/ancestor :: inventory/totalprice示例

我们必须稍微改变您的示例文档,以便有用地研究此示例

<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>
Run Code Online (Sandbox Code Playgroud)

让我们说重点是元素焦点项目.要评估before-sibling :: pop/ancestor :: inventory/totalprice之间的表达式,请按照以下步骤操作

  1. preceding-sibling :: pop选择所有前面的pop元素到focus-item.这将评估为一个节点的序列.
  2. 对于左手序列中的每个项目(只发生一个pop元素),将此项目设置为临时焦点项目,并评估/运算符右侧的表达式,即...

    ancestor::inventory
    
    Run Code Online (Sandbox Code Playgroud)

    只有一个这样的节点,它是祖先库存节点.因此,第一个/运算符评估一个库存节点的序列.

  3. 现在我们评估第二个/及其右侧操作数表达式总价的影响.对于左手序列中的每个项目(只发生一个库存节点),将其设置为临时焦点项并评估总价.

  4. totalprice是child :: totalprice的缩写.临时焦点节点的子轴上只有一个总价格元素,因此最终结果是一个节点的序列,即总价格节点.

图解理解

请查看此页面以获取轴的图示.

这是previous-sibling ::的页面图的副本.其中参考节点是Charlie,前兄弟::轴上的节点是绿色.它是唯一的这样的节点. 在此输入图像描述


Oki*_*Oth 5

轴对于在节点树中导航很有用。因此,这取决于您的问题,哪种轴有用。

以下样式表说明了其中的差异。

<?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>
Run Code Online (Sandbox Code Playgroud)