我正在使用Muenchian方法对XML文档中的节点进行分组.
作为输出的一部分,我想选择我没有分配密钥的所有节点.
我试过了
<xsl:apply-templates select="*[key('kcWWPN','')]"/>
Run Code Online (Sandbox Code Playgroud)
但这似乎没有正常工作,因为它没有选择任何节点.
有关正确方法的任何建议吗?
作为输出的一部分,我想选择我没有分配密钥的所有节点.
好问题,+ 1.
以下是两种不同但简单的解决方案:
为简单起见,我假设我们只键入元素,但下面的两个解决方案自然可以扩展到其他类型的节点.
I.简单地说,定义一个 反键:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kDByClass" match="d" use="@class"/>
<xsl:key name="kCounterKey" match="*[not(self::d)]" use="."/>
<xsl:template match="*[key('kCounterKey', .)]">
Counter Keyed: <xsl:value-of select="name()"/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当此转换应用于以下XML文档时(从@lwburk借用):
<root>
<d class="test">1</d>
<d class="test">2</d>
<d class="something">1</d>
<q>3</q>
</root>
Run Code Online (Sandbox Code Playgroud)
产生了想要的正确结果:
Counter Keyed: root
Counter Keyed: q
Run Code Online (Sandbox Code Playgroud)
II.使用所有元素和所有键控元素的集合差异(后者使用Muenchian分组找到):
这个解决方案比第一个简单,因为不需要组成一个反键:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kDByClass" match="d" use="@class"/>
<xsl:key name="kCounterKey" match="*[not(self::d)]" use="."/>
<xsl:variable name="vKeyedValues" select=
"//*[generate-id()
= generate-id(key('kDByClass', @class)[1])
]
/@class
"/>
<xsl:variable name="vKeyedElements" select=
"key('kDByClass', $vKeyedValues)"/>
<xsl:variable name="vNonKeyedElements" select=
"//*[not(count(.|$vKeyedElements) = count($vKeyedElements))]
"/>
<xsl:template match="/">
<xsl:for-each select="$vNonKeyedElements">
Not Keyed: <xsl:value-of select="name()"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当此转换应用于同一XML文档(上面)时,再次生成相同的正确结果:
Not Keyed: root
Not Keyed: q
Run Code Online (Sandbox Code Playgroud)
注意:当密钥不是节点时,最后一个解决方案可能不起作用,但是函数的结果可能不起作用,例如substring-before().在这种情况下,我们只需修改原始密钥,因此它的use属性就是:use="."并将此解决方案与修改后的原始密钥一起使用.可以证明这个过程产生了正确的,想要的元素集.