我的 xslt 1.0 模板中有两个变量,每个变量包含一个节点集(使用 xpath 选择)。我想确定一个变量中的节点集是否包含在另一个变量中的节点集中。例如,假设我有一个包含嵌套部分的章节。我想看看$b
是否包含在$a
中:
<xsl:variable name="a" select="chapter//section" />
<xsl:variable name="b" select="chapter//section" />
我试图获取节点集的交集,以查看$a
是否是$a
和$b
共享的第一个公共元素,但这不起作用:
<xsl:if test="$a/ancestor-or-self::*[count(.|$b) = count($b/ancestor::*)][1] = $a">
添加一些上下文。我正在使用这个 xslt 为 html 页面树创建一个选项卡式界面,我试图解决的问题是将 class="current" 放在正确的选项卡上。通过测试每个部分以查看它是否是选项卡部分的子部分,它获得 class="current",因此选项卡的样式将看起来好像在顶部。
我认为您可以简单地使用count($a) = count($a|$b)
.如果$b中有任何节点不在$a中,则计数将不同。
扩展Michael Kay的好答案:
当节点$n
属于节点集$ns
时?
如果节点属于节点集,则节点与节点集的并集不会导致更大的节点集 - 因此联合中的节点数不得大于(实际上必须等于)原始节点集中的节点数。
若要使用 XPath 表达式来表达这一点,请执行以下操作:
count($n | $ns) = count($ns)
现在,相同的逻辑告诉我们,节点集$ns1
是节点集的子集,$ns2
当两个节点集的联合不包含比较大节点集更多的元素时:
count($ns1 | $ns2) = count($ns2)
如果我们想测试$ns1
是否是$ns2
的真正子集:
count($ns1 | $ns2) = count($ns2)
and
count($ns2) > count(ns1)
我能够使用不同的方法解决问题。我测试了$b
的每个祖先元素,看看它是否与$a
具有相同的xml:id:
<xsl:if test="boolean($b/ancestor-or-self::[@xml:id=$a/@xml:id])">
虽然这没有使用交集,但它确实会告诉$a
是否包含$b
。