我一直在尝试编写一个XPath语句,该语句将选择节点的第一个前同级。该同级节点应具有特定节点作为其子节点。
例如:
<a>
<c></c>
....
<b></b>
</a>
<a></a>
....
....
<a></a>
<a>
<b> start </b>
</a>
在上面的XML中,如果我的上下文位于节点a
,该节点在其子b
中具有start
文本。如何选择前面的节点a
其子节点b
?
我尝试了preceding-sibling::*[b][1]
但它仅在b
是其第一个孩子时才选择节点a
。我也尝试了preceding-sibling::*[1][b]
但它只检查前面的第一个a
节点,如果它不包含b
,测试失败。
注意:我正在使用 XSLT 1.0
谁能给我一个解决方案?
提前感谢!!
我相信:
preceding-sibling::*[b][1]
或优选:
preceding-sibling::a[b][1]
应该工作得很好。
我尝试在兄弟姐妹之前::*[b][1],但它只选择节点 a 如果 b 是它的第一个孩子。
我不认为是这样。
像这样。("第一个有<b>
孩子的兄弟姐妹"):
preceding-sibling::a[b][1]
或这个("前面的第一个兄弟姐妹,但前提是它有一个<b>
孩子"):
preceding-sibling::a[1][b]
多个谓词必须一个接一个地为真。因此,这:
preceding-sibling::a[b and position() = 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>