我一直在尝试编写一个XPath语句,它将选择节点的第一个前一个兄弟。那个兄弟应该有一个特定的节点作为它的孩子。
例如:
<a>
<c></c>
....
<b></b>
</a>
<a></a>
....
....
<a></a>
<a>
<b> start </b>
</a>
在上面的XML中,如果我的上下文位于其子a
内有start
文本的节点b
。如何选择孩子为a
的前一个节点b
?
我尝试了preceding-sibling::*[b][1]
,但如果a
是其第一个孩子,则只选择节点b
。我也尝试了preceding-sibling::*[1][b]
,但它只检查前面的第一个a
节点,如果它不包含b
,则测试失败。
注意:我正在使用XSLT 1.0
有人能建议我解决方案吗?
Thnx提前!!
答案 0 :(得分:4)
喜欢这个。 (“第一个有<b>
孩子的兄弟姐妹”:
preceding-sibling::a[b][1]
或者这个(“前面的第一个兄弟姐妹,但只有它有一个<b>
孩子”):
preceding-sibling::a[1][b]
多个谓词必须一个接一个地为真。因此,这个:
preceding-sibling::a[b and position() = 1]
相当于第二个表达式,但不是第一个表达式。
答案 1 :(得分:3)
我相信:
preceding-sibling::*[b][1]
或者最好:
preceding-sibling::a[b][1]
应该可以正常工作。
我尝试过previous-sibling :: * [b] [1],但它只选择节点a if b 是它的第一个孩子。
我认为不是这样。
答案 2 :(得分:1)
使用此输入:
<root>
<a>
<c></c>
<b>SUCCESS</b>
</a>
<a>FAIL</a>
<a>FAIL</a>
<a>
<b> start </b>
</a>
</root>
和这个样式表
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a[b[.=' start ']]">
<xsl:copy>
<xsl:value-of select="preceding-sibling::a[b]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出
<root>
<a>
<c/>
<b>SUCCESS</b>
</a>
<a>FAIL</a>
<a>FAIL</a>
<a>SUCCESS</a>
</root>