XSL 1.0来自模板的不同值

时间:2013-08-30 09:52:28

标签: xml xslt xslt-1.0

有人能帮我解决这个问题吗?

这是我的XML -

<grandparent>
  <parent>
    <child>apple</child>
  </parent>
  <parent>
    <child>apple</child>
    <child>orange</child>
    <child>apple</child>
    <child>apple</child>
    <child>apple</child>
  </parent>
  <parent>
    <child>pear</child>
    <child>apple</child>
    <child>pear</child>
    <child>pear</child>
  </parent>
</granparent>

我有一个模板,我将父传递给它并且它会吐出所有子标签,但我希望它只吐出唯一的子值。

我已经进行了搜索,并且每个人都建议使用密钥似乎不起作用,因为它似乎只获得祖父母范围内的唯一值,而不是父母的范围。

这就是我所拥有的 -

<xsl:template name="uniqueChildren">
  <xsl:param name="parent" />

  <xsl:for-each select="$parent/child">
    <xsl:value-of select="." />
  </xsl:for-each>
</xsl:template>

目前显示 -

apple
apple orange apple apple apple
pear apple pear pear

我尝试密钥时的代码 -

<xsl:key name="children" match="child" use="." />

<xsl:template name="uniqueChildren">
  <xsl:param name="parent" />

  <xsl:for-each select="$parent/child[generate-id() = generate-id(key('children', .)[1])]">
    <xsl:value-of select="." />
  </xsl:for-each>
</xsl:template>

当我尝试使用它显示的键时 -

apple
orange
pear

我希望它展示 -

apple
apple orange
pear apple

1 个答案:

答案 0 :(得分:0)

您与关键方法非常接近,诀窍是您需要将父节点的标识作为分组键的一部分包含在内:

<xsl:key name="children" match="child" use="concat(generate-id(..), '|', .)" />

<xsl:template name="uniqueChildren">
  <xsl:param name="parent" />

  <xsl:for-each select="$parent/child[generate-id() = generate-id(
           key('children', concat(generate-id($parent), '|', .))[1])]">
    <xsl:value-of select="." />
  </xsl:for-each>
</xsl:template>

这会创建“<id-of-parent>|apple”,“<id-of-parent>|orange”等格式的键值。


编辑:在您的评论中,您说“在我的实际数据中,子节点不是父节点的直接子节点。父节点和子节点之间有2个级别,例如父/././ child”

在这种情况下,相同的原理有效,您只需稍微调整一下键即可。关键是键值需要包含定义唯一性检查范围的节点的generate-id。所以,如果你知道你之间总是有两个等级(parent/x/y/child)那么你就会使用

<xsl:key name="children" match="child"
   use="concat(generate-id(../../..), '|', .)" />

child元素可能位于parent内的不同级别,那么您可以使用类似

的内容
<xsl:key name="children" match="child"
   use="concat(generate-id(ancestor::parent[1]), '|', .)" />

ancestor::parent[1]是目标元素的最近祖先,其名称为parent