我想使用XSLT根据另一个节点列表的内容过滤节点列表。具体来说,我想过滤一个节点列表,以便从结果节点列表中删除具有相同id属性的元素。应优先考虑两个节点列表中的一个。
我最初想象实现这个的方式是做这样的事情:
<xsl:variable name="filteredList1" select="$list1[not($list2[@id_from_list1 = @id_from_list2])]"/>
问题是上下文节点在$ list2的谓词中发生了变化,因此我无法访问属性@ id_from_list1。由于这些范围限制,我不清楚如何使用嵌套谓词以这种方式从外部节点列表引用属性。
为了解决上下文节点的问题,我尝试创建一个涉及for-each循环的解决方案,如下所示:
<xsl:variable name="filteredList1">
<xsl:for-each select="$list1">
<xsl:variable name="id_from_list1" select="@id_from_list1"/>
<xsl:if test="not($list2[@id_from_list2 = $id_from_list1])">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
但这不能正常工作。我也不清楚它是如何失败的......使用上述技术,filteredList1的长度为1,但似乎是空的。这是一种奇怪的行为,无论如何,我觉得必须有更优雅的方法。
我很感激任何人都可以提供任何指导。感谢。
答案 0 :(得分:4)
使用此XPath单行:
<强> $vList1[not(@id = $vList2/@id)]
强>
答案 1 :(得分:1)
据我所知,使用$ var []语法不起作用。有效的是:expr1 / [expr2 = $ var]和func1($ var)。
你可以做的只是嵌入在if测试中产生$ list2的表达式:
<xsl:for-each select="$list1">
<xsl:variable name="id" select="@id_from_list1"/>
<xsl:if test="not(expr2[@id_from_list2 = $id ])">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
<xsl:copy-of select="$list2"/>
用实际表达式替换expr2。