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, I found ancestor explanation. and the chart from their website makes easier to understand.
我对xslt非常陌生,发现它可以是简单的,也可以是复杂的。我想澄清一些概念。在谷歌搜索之后,我找到了祖先的解释。他们网站上的图表更容易理解。
But I still don't understand preceding-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>
so how do I read this preceding-sibling::pop/ancestor::inventory/totalprice
那么,我该如何解读这段话呢?兄弟姐妹:pop/祖先::inventory/totalprice
ancestor::inventory/totalprice = product\inventory\totalprice preceding-sibling::pop - I dont understand this one then how to read all together?
祖先:库存/totalprice =产品\库存价格(\totalprice before) -同胞:pop -我不懂这个,那怎么读呢?
Many thanks
非常感谢
3 个解决方案
#1
62
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 ocurrs before the reference one. The order of the preceding-sibling axis is the reverse document order. Take a look at this document:
axis是导航的一个轴,它包括所有前面的兄弟元素到焦点元素。我们所说的“同胞”指的是具有引用项相同父元素的不同元素。“前面”指的是在引用节点之前的节点。同级轴的顺序是相反的文档顺序。请看这份文件:
<fruit>
<banana>
<lady-finger-banana/>
</banana>
<apple/>
<pear/>
<kiwi/>
</fruit>
If the focus node is pear, then the sequence preceding-sibling::* is ...
如果焦点节点是pear,则序列在::*之前。
- apple
- 苹果
- 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
- 兄弟姐妹:*[1]是苹果
- preceding-sibling::*[ 2] is the banana
- 兄弟姐妹:*[2]是香蕉
- count( preceding-sibling::*) is 2
- 计数(preceding-sibling::*)是2
- preceding-sibling::apple[ 1] is also the apple
- 先例:苹果[1]也是苹果。
- preceding-sibling::banana[ 1] is the banana
- 兄弟姐妹:香蕉[1]是香蕉
- preceding-sibling::*[ 3] is absent or the empty sequence
- 兄弟:*[3]不在或为空序列
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
假设焦点是元素焦点-项目。要计算表达式之前的值——同胞:pop/祖::inventory/totalprice遵循以下步骤
- preceding-sibling::pop selects all the preceding pop elements to focus-item. This evaluates to a sequence of one node.
- :pop选择所有前面的pop元素到焦点项。这将计算为一个节点的序列。
-
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 ...
对于左侧的每一个项目(只有一个pop元素是这样的),将这个项目设置为一个临时的焦点项目,并评估/运算符右边的表达式。
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.
只有一个这样的节点,即祖先库存节点。因此,第一个/操作符计算一个清单节点的序列。
-
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.
现在我们来评估第二个/及其右操作数表达式的总价格的影响。对于左手序列中的每个项(通常只有一个库存节点),将其设置为一个临时焦点项并计算totalprice。
- 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.
- totalprice是child的简称:totalprice。临时焦点节点的子轴上只有一个total price元素,因此最终结果是一个节点的序列,即total price节点。
Understanding by Diagrams
Please look at this page for an illustration of axises.
请看这一页,以说明axises。
Here is a copy of that page's 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.
这是该页前的同级关系图的副本:。其中引用节点为Charlie,前面的节点为::axis为绿色。它是唯一的这样的节点。
#2
3
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>
#3
2
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.
在当前节点级别中,“兄弟”获取先于它的所有元素的“兄弟”。除非您指定一个或多个前面的兄弟姐妹使用xpath表达式。如果您指定了一个具有xpath的特定的优先级,那么它总是以方括号中的1开头。
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.
祖先是与表达式匹配的第一个匹配的祖先。它返回到节点树中,根据当前的位置来查看匹配表达式。如果你在product/inventory/drink/pop或just /pop那么祖先库存/totalprice只寻找第一个发生的事件它应该返回一个指向那个匹配案例的指针否则它将指向什么也不会,你仍然指向pop。
#1
62
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 ocurrs before the reference one. The order of the preceding-sibling axis is the reverse document order. Take a look at this document:
axis是导航的一个轴,它包括所有前面的兄弟元素到焦点元素。我们所说的“同胞”指的是具有引用项相同父元素的不同元素。“前面”指的是在引用节点之前的节点。同级轴的顺序是相反的文档顺序。请看这份文件:
<fruit>
<banana>
<lady-finger-banana/>
</banana>
<apple/>
<pear/>
<kiwi/>
</fruit>
If the focus node is pear, then the sequence preceding-sibling::* is ...
如果焦点节点是pear,则序列在::*之前。
- apple
- 苹果
- 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
- 兄弟姐妹:*[1]是苹果
- preceding-sibling::*[ 2] is the banana
- 兄弟姐妹:*[2]是香蕉
- count( preceding-sibling::*) is 2
- 计数(preceding-sibling::*)是2
- preceding-sibling::apple[ 1] is also the apple
- 先例:苹果[1]也是苹果。
- preceding-sibling::banana[ 1] is the banana
- 兄弟姐妹:香蕉[1]是香蕉
- preceding-sibling::*[ 3] is absent or the empty sequence
- 兄弟:*[3]不在或为空序列
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
假设焦点是元素焦点-项目。要计算表达式之前的值——同胞:pop/祖::inventory/totalprice遵循以下步骤
- preceding-sibling::pop selects all the preceding pop elements to focus-item. This evaluates to a sequence of one node.
- :pop选择所有前面的pop元素到焦点项。这将计算为一个节点的序列。
-
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 ...
对于左侧的每一个项目(只有一个pop元素是这样的),将这个项目设置为一个临时的焦点项目,并评估/运算符右边的表达式。
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.
只有一个这样的节点,即祖先库存节点。因此,第一个/操作符计算一个清单节点的序列。
-
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.
现在我们来评估第二个/及其右操作数表达式的总价格的影响。对于左手序列中的每个项(通常只有一个库存节点),将其设置为一个临时焦点项并计算totalprice。
- 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.
- totalprice是child的简称:totalprice。临时焦点节点的子轴上只有一个total price元素,因此最终结果是一个节点的序列,即total price节点。
Understanding by Diagrams
Please look at this page for an illustration of axises.
请看这一页,以说明axises。
Here is a copy of that page's 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.
这是该页前的同级关系图的副本:。其中引用节点为Charlie,前面的节点为::axis为绿色。它是唯一的这样的节点。
#2
3
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>
#3
2
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.
在当前节点级别中,“兄弟”获取先于它的所有元素的“兄弟”。除非您指定一个或多个前面的兄弟姐妹使用xpath表达式。如果您指定了一个具有xpath的特定的优先级,那么它总是以方括号中的1开头。
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.
祖先是与表达式匹配的第一个匹配的祖先。它返回到节点树中,根据当前的位置来查看匹配表达式。如果你在product/inventory/drink/pop或just /pop那么祖先库存/totalprice只寻找第一个发生的事件它应该返回一个指向那个匹配案例的指针否则它将指向什么也不会,你仍然指向pop。