JLR*_*she 4 xslt xpath xpath-1.0
(我发布这个自我回答的问题,因为通常提供的解决这个问题的方法是不必要的冗长,我想直接记录.我找不到现有的SO问题,但是如果有的话,请将此作为副本关闭.)
我正在寻找一种方法来执行XPath选择,只有当它符合某个条件时才选择当前节点.例如,当我想有条件地将XSLT模板应用于当前节点时,这将非常有用:
<xsl:template match="Device">
<div>
<h2><xsl:value-of select="Name" /></h2>
<xsl:apply-templates select="???[Featured = 'true']" mode="featured" />
<p><xsl:value-of select="Description" /></p>
</div>
</xsl:template>
<xsl:template match="Book">
<div>
<h2><xsl:value-of select="Title" /></h2>
<xsl:apply-templates select="???[FeaturedBook = 'true']" mode="featured" />
<h3><xsl:value-of select="Author" /></h3>
<p><xsl:value-of select="Summary" /></p>
</div>
</xsl:template>
<xsl:template match="node()" mode="featured">
<p class='featured-notice'>This is a featured item!
<a href="/AddToCart?productId={Id}">Buy now</a> to get a 15% discount.
</p>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
我尝试过使用.[Featured = 'true'],但是我遇到了语法错误.我怎样才能做到这一点?
我不打算在这里添加输入和输出,因为它们与问题相关并且会使它非常长,但是如果你想看到我的想法,我把它们放在这里:输入,输出.
JLR*_*she 11
由于语法.[predicate]规则,XPath 1.0中不允许使用该语法(有关详细信息,请参阅本文末尾).
我发现的100%建议说唯一的选择是self::node()用于此:
self::node()[Featured = 'true']
Run Code Online (Sandbox Code Playgroud)
这个XPath测试仪甚至专门设计用于告诉用户self::node()[predicate]如果尝试使用它们.[predicate],但这不是唯一的选择.
一个有效且更简洁的选项是将缩写步骤包装在括号中:
(.)[Featured = 'true']
Run Code Online (Sandbox Code Playgroud)
这完全适用于XPath 1.0语法规则(在我看来,更加清晰).
您也可以使用此方法 ..缩写步骤,甚至多个级别:
Select grandfather node if it is featured
../..[Featured = 'true'] - Not valid
../../../*[Featured = 'true'] - Valid, but not accurate
../../self::node()[Featured = 'true'] - Valid, but verbose
(../..)[Featured = 'true'] - Valid
Run Code Online (Sandbox Code Playgroud)
.[predicate]在XPath 1.0中使用它
以下是XPath 1.0中"步骤"的定义(基本上,由斜杠分隔的XPath节点选择表达式的部分称为"步骤"):
[4] Step :: = AxisSpecifier NodeTest Predicate*| AbbreviatedStep
这意味着一步包含两个可能的选项之一:
.或..没有选项可以使用缩写步骤,后跟谓词.