XSLT 2 是首选,我希望使这更容易。
给定一个类似于
<doc xmlns:bob="bob.com">
<element bob:name="fred" bob:occupation="Dr">Stuff</element>
<element bob:name="Bill" bob:occupation="Dr" bob:birthMonth="Jan"/>
<element>Kill Me</element>
<element bob:name="fred" bob:occupation="Dr">different Stuff</element>
</doc>
我想拥有基于 bob 命名空间中所有属性的所有唯一元素。这是一个有代表性的样本,但我会有更深的嵌套,所以我希望它遍历树
*[@bob:*] and get the unique set of those.
希望的输出看起来像
<doc xmlns:bob="bob.com">
<element bob:name="fred" bob:occupation="Dr">Stuff</element>
<element bob:name="Bill" bob:occupation="Dr" bob:birthMonth="Jan"/>
</doc>
其中一个元素因没有任何 @bob:* 属性而被删除,另一个元素因仅基于属性而与第一个元素重复而被删除。
我试图使用钥匙,但似乎做得不对
<xsl:key name="BobAttributes" match="//*" use="./@bob:*" />
我还尝试创建一个连接所有 @bob 属性的函数,但这似乎也没有达到我的预期。
<xsl:key name="BobAttributes" match="//*" use="functx:AllBobConcat(.)" />
<xsl:function name="functx:AllBobConcat" as="xs:string*"
xmlns:functx="http://www.functx.com" >
<xsl:param name="nodes" as="node()*"/>
<xsl:for-each select="$nodes/@bob:*">
<xsl:value-of select="local-name(.)"/>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:function>
在这两种情况下,我都使用“简单”XSL 来过滤掉唯一的 XSL,也许我在这里搞砸了?此处添加的变量用于尝试和调试。
<xsl:template match="*[@ism:*]" priority="100">
<xsl:variable name="concat">
<xsl:value-of select="functx:AllBobConcat(.)"/>
</xsl:variable>
<xsl:variable name="myID">
<xsl:value-of select="generate-id() "/>
</xsl:variable>
<xsl:variable name="Keylookup">
<xsl:value-of select="key('BobAttributes', $concat)"/>
</xsl:variable>
<xsl:value-of select="concat($concat, $Keylookup, $myID)"/>
<xsl:if test="generate-id() = generate-id(key('BobAttributes', $concat)[1])">
<xsl:apply-templates select="." mode="copy"/>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()" mode="copy">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
期待听到我忽略了什么简单的事情,或者我应该采取完全不同的酷方法。