29

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

但是我还是不明白presing-sibling

<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>

那么我该如何阅读这个previous-sibling::pop/ancestor::inventory/totalprice

祖先::库存/总价格 = 产品\库存\总价格前兄弟::流行 - 我不明白这个然后如何一起阅读?

非常感谢

4

3 回答 3

79

前兄弟:: 轴

preceding-sibling::轴是导航轴,包括焦点元素之前的所有同级元素。“同级”是指与引用项具有相同父项的不同元素。“在前”是指出现在参考节点之前的节点。preceding-sibling轴的顺序是逆文档顺序。看看这个文件:

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

如果焦点节点是梨,那么序列preceding-sibling::*是...

  1. 苹果
  2. 香蕉

注:水果、梨、小指香蕉和猕猴桃不按顺序排列。

所以以下是正确的:

  • preceding-sibling::*[ 1]是苹果
  • preceding-sibling::*[ 2]是香蕉
  • count( preceding-sibling::*)是 2
  • preceding-sibling::apple[ 1]也是苹果
  • preceding-sibling::banana[ 1]是香蕉
  • preceding-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>

让我们说焦点在元素焦点项目上。要评估表达式,请执行preceding-sibling::pop/ancestor::inventory/totalprice以下步骤:

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

    ancestor::inventory
    

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

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

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

用图表理解

这是一个图表preceding-sibling::。其中,参考节点是 Charlie,preceding-sibling::轴上的节点是绿色的。它是唯一这样的节点。

在此处输入图像描述

于 2012-09-10T08:31:08.400 回答
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>
于 2012-09-10T08:45:45.427 回答
2

Preceding-sibling 获取当前节点级别中在它之前的所有元素兄弟。除非您使用 xpath 表达式指定一个或多个前面的同级。如果您使用 xpath 指定特定的前置兄弟,它始终以方括号中的 1 开头。

Ancestor 是匹配表达式的第一个匹配的祖先。因此,它会返回节点树以根据您当前指向的位置查看匹配的表达式。因此,如果您在 product/inventory/drink/pop 或只是 /pop 那么祖先 inventory/totalprice 只是寻找第一次出现,它应该只返回一个指向该匹配案例的指针,否则它将指向任何内容而你' 仍然会指向流行音乐。

于 2012-09-10T08:18:29.210 回答