如何在xslt/xpath中匹配具有特定兄弟元素的元素

4

我正在尝试匹配所有具有b兄弟节点的a/c元素。我已经尝试了:

<xsl:template match="a/b/../c">

但是我在Saxon中得到了“无法将表达式{...}转换为模式”的错误。

我的XSLT / XPath技能最多只能算基础水平...

2个回答

5
<xsl:template match="a[b]/c">

解释:匹配任何一个作为元素子节点的元素,并且这个元素有一个子节点

你还应该能够在谓词中使用..

<xsl:template match="a/c[../b]">

这与您尝试的类似。

您不能直接在匹配模式中使用..(即在谓词之外),因为模式不是XPath表达式,尽管它们看起来和行为非常相似。特别地,只允许“向下”轴(child::descendant::attribute::)直接出现在模式中。(规范允许的唯一显式轴是child::attribute::。通过模式步骤之间的//,隐含允许descendant::。Saxon似乎在这里有点弯曲规则,允许显式的descendant::轴,甚至是descendant-or-self::!)

限制轴的原因是(a)模式中很少需要其他轴,(b)这使得XSLT处理器在测试匹配时更加高效。

但是,在模式中的谓词使用与XPath表达式相同的语法规则进行定义(在XSLT 1.0中有一些限制,如不允许变量引用或current())。因此,您可以使用其他轴,如parent::或缩写形式的..


谢谢 - 这非常有帮助。我最终发现 .. 可以在谓词中使用(在发现什么是谓词后不久),但我对解释一无所知,这个答案正是我所期望的,而且更多 - 它帮助我理解了。 - user533832
加上 a[b]/c 比我想出来的更整洁 :-) - user533832

1

这个XPath表达式似乎可以完成任务(可能不是最优的):

//a|//c[following-sibling::b or preceding-sibling::b]

编辑:

如果LarsH是正确的,那么应该是//a/c而不是//a|//c


1
我相信当OP说a/c时,他的意思是“c元素是a的子元素”,而不是“ac”。 - LarsH
此外,您可以省略匹配模式开头的 // - LarsH
@LarsH 没错,你说得对。Lev,如果我表达不清楚,对不起 - 请告诉我是否应该用不同的方式表达我的问题,这会帮助我学习! - user533832
@Jack,不,我猜是我的错 :) LarsH,对于我正在测试的工具,需要// - Lev Levitsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接