Xslt 将谓词应用于当前节点
(我发布这个自我回答的问题是因为这个问题通常提供的解决方案是不必要的冗长,我想澄清一下。我找不到关于这个问题的现有SO问题,但如果有,请将其作为副本关闭。) 我正在寻找一种执行XPath选择的方法,仅当当前节点符合某个条件时才选择它。例如,当我希望有条件地将XSLT模板应用于当前节点时,这将非常有用:Xslt 将谓词应用于当前节点,xslt,xpath,xpath-1.0,Xslt,Xpath,Xpath 1.0,(我发布这个自我回答的问题是因为这个问题通常提供的解决方案是不必要的冗长,我想澄清一下。我找不到关于这个问题的现有SO问题,但如果有,请将其作为副本关闭。) 我正在寻找一种执行XPath选择的方法,仅当当前节点符合某个条件时才选择它。例如,当我希望有条件地将XSLT模板应用于当前节点时,这将非常有用: <xsl:template match="Device"> <div> <h2><xsl:value-of select="Name" /&g
<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>
这是一个特色项目!
得到15%的折扣。
我尝试过使用[Featured='true']
,但出现语法错误。我该怎么做
我不打算在这里添加输入和输出,因为它们与问题无关,并且会使问题变得非常长,但如果您想了解我的想法,我将它们放在这里:,。由于语法规则,XPath 1.0中不允许使用语法
[谓词]
(详见本帖末尾)
我发现的100%的建议都说,唯一的选择是使用self::node()
实现以下目的:
self::node()[Featured = 'true']
甚至是专门设计来告诉用户,如果他们试图使用[谓词]
,就要使用self::node()[谓词]
,但这不是唯一的选项
一个有效且更简洁的选项是将缩写步骤用括号括起来:
(.)[Featured = 'true']
根据XPath1.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中使用
[谓词]
以下是XPath 1.0中“步骤”的定义(基本上,用斜杠分隔的XPath节点选择表达式片段称为“步骤”):
[4] 步骤::=AxisSpecifier节点测试谓词*|缩写步骤
这意味着一个步骤包括两个可能选项之一:
- 轴说明符(可以是空字符串),后跟节点测试,后跟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>
这是一个特色项目!
得到15%的折扣。
@IanRoberts对于问题中提供的示例来说可能是这样,因为它是关于XSLT的,但是current()
不是XPath标准的一部分,并且可能存在
和current()
引用不同事物的情况(例如在谓词内部)您可能想使用
。问题中的XSLT纯粹是一般问题的说明性示例,您在那里发布的内容并不符合示例的意图。我对示例进行了编辑,以使该意图更清晰。您似乎专注于将谓词应用于当前节点。您所说的是-I'm我在这里的产品模板-现在检查,看看我是否应该做些什么。更好的方法是外部化检查,这样你就永远不会去错误的模板在第一个地方,你可以通过放置谓词在模板匹配语句。我编辑了一点代码(不多)我一直专注于将谓词应用于当前节点,因为这就是问题所在。有时这样做很有用。正如我已经说过的,XSLT示例纯粹是一个示例。尽管如此,如果您认为有一种更优雅的方法来实现示例所说明的内容(我很抱歉在事后更改了它),然后我欢迎您演示。您当前的示例没有告诉我任何事情。我编辑了这个问题以添加到示例输入和输出的链接。不,语法不允许它的事实并不能证明任何事。如果有什么,事实是[predicate]
在XQuery中是允许的,XPath 2.0+表明它是值得的。这是公平的。总是有其他的方法来做事情。您必须将{Id}
更改为{../Id}
,但您的示例是有效的。我仍然坚持我的主张,即这种语法值得了解,并且具有实际应用,即使我提供的示例不是防弹的。