所以我很难理解为什么一个 XPath 表达式得到我想要的节点,而另一个没有。
首先,xml:
<doc>
<source id="225" clientID="567" matterID="225" level="2" />
<source id="226" clientID="993" matterID="226" level="2" />
<dest id="185" level="7" />
<dest id="226" level="7" />
</doc>
我的 xsl 模板中的键定义如下:
<xsl:key name="sourceId" match="//source" use="@id" />
<xsl:key name="destId" match="//dest" use="@id" />
<xsl:key name="destLevel" match="//dest" use="@level" />
我正在寻找的是源节点,它与 id 上的 dest 节点匹配,但具有不同的 level 属性。我认为可以在我脑海中使用的应用模板如下:
<xsl:apply-templates select="source[key('destId', @id) and not(key('destLevel', @level))]" mode="update" />
但这似乎不起作用。一位同事建议在与我不想要的节点匹配的表达式周围放置一个 not ,经过大量试验和错误,我认为这可能有效,但没有效果:
<xsl:apply-templates select="source[not(not(key('destId', @id)) or not(key('destLevel', @level)))]" mode="update" />
谁能告诉我我需要什么来解决这个问题?
编辑:我以前以为我已经用第二个查询解决了这个问题,但似乎我错了。
====解决方案====
Dimitre Novatchev 详细介绍了解决此问题的不同方法,但我的最终解决方案实际上与他的略有不同。
本质上,我使用结合了这两个属性的 concat() 函数创建了一个虚拟键。这样,我可以找到与 id 匹配的节点,但不是 id 级别的组合。
额外的钥匙:
<xsl:key name="destByIdAndLevel" match="//dest" use="concat(@id,'+',@level)" />
更改了应用模板调用:
<xsl:apply-templates select="source[key('destId', @id) and not(key('destByIdAndLevel',concat(@id,'+',@level)))]" mode="update" />