将谓词应用于当前节点
Apply a predicate to the current node
(我发布了这个自我回答的问题,因为针对这个问题通常提供的解决方案不必要地冗长,我想澄清一下。我找不到现有的 SO对此有疑问,但如果有,请将其作为副本关闭。)
我正在寻找一种方法来执行 XPath selection 到 select 当前节点,只有当它符合特定条件时。这将很有用,例如,当我想有条件地将 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>
我试过使用 .[Featured = 'true']
,但出现语法错误。我该怎么做?
我不打算在这里添加输入和输出,因为它们与问题无关并且会使它变得非常长,但是如果你想看看我的想法,我有将它们放在这里:input, output.
由于语法规则,XPath 1.0 中不允许使用语法 .[predicate]
(有关详细信息,请参阅此 post 的末尾)。
我找到的 100% 的建议都说唯一的选择是为此使用 self::node()
:
self::node()[Featured = 'true']
This XPath tester 甚至专门设计用于告诉用户如果他们尝试使用 .[predicate]
,则使用 self::node()[predicate]
,但这不是唯一的选择。
一个有效且更简洁的选择是将缩写步骤括在括号中:
(.)[Featured = 'true']
这完全符合 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
附录: 为什么不能在 XPath 1.0 中使用 .[predicate]
下面是XPath 1.0中"step"的定义(基本上,XPath节点选择表达式中用斜线分隔的部分称为"steps"):
[4] Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep
这意味着一个步骤包含两个可能选项之一:
- 一个轴说明符(可以是空字符串),后跟一个节点测试,后跟0个或多个谓词
- 一个简化的步骤:
.
或 ..
没有选项可以让谓词后跟一个缩写步骤。
<xsl:template match="Device">
<div>
<h2><xsl:value-of select="Name" /></h2>
<xsl:apply-templates select="Featured[. = 'true']" />
<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']" />
<h3><xsl:value-of select="Author" /></h3>
<p><xsl:value-of select="Summary" /></p>
</div>
</xsl:template>
<xsl:template match="FeaturedBook|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>
(我发布了这个自我回答的问题,因为针对这个问题通常提供的解决方案不必要地冗长,我想澄清一下。我找不到现有的 SO对此有疑问,但如果有,请将其作为副本关闭。)
我正在寻找一种方法来执行 XPath selection 到 select 当前节点,只有当它符合特定条件时。这将很有用,例如,当我想有条件地将 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>
我试过使用 .[Featured = 'true']
,但出现语法错误。我该怎么做?
我不打算在这里添加输入和输出,因为它们与问题无关并且会使它变得非常长,但是如果你想看看我的想法,我有将它们放在这里:input, output.
由于语法规则,XPath 1.0 中不允许使用语法 .[predicate]
(有关详细信息,请参阅此 post 的末尾)。
我找到的 100% 的建议都说唯一的选择是为此使用 self::node()
:
self::node()[Featured = 'true']
This XPath tester 甚至专门设计用于告诉用户如果他们尝试使用 .[predicate]
,则使用 self::node()[predicate]
,但这不是唯一的选择。
一个有效且更简洁的选择是将缩写步骤括在括号中:
(.)[Featured = 'true']
这完全符合 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
附录: 为什么不能在 XPath 1.0 中使用
.[predicate]
下面是XPath 1.0中"step"的定义(基本上,XPath节点选择表达式中用斜线分隔的部分称为"steps"):
[4] Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep
这意味着一个步骤包含两个可能选项之一:
- 一个轴说明符(可以是空字符串),后跟一个节点测试,后跟0个或多个谓词
- 一个简化的步骤:
.
或..
没有选项可以让谓词后跟一个缩写步骤。
<xsl:template match="Device">
<div>
<h2><xsl:value-of select="Name" /></h2>
<xsl:apply-templates select="Featured[. = 'true']" />
<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']" />
<h3><xsl:value-of select="Author" /></h3>
<p><xsl:value-of select="Summary" /></p>
</div>
</xsl:template>
<xsl:template match="FeaturedBook|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>