XSL 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>

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

我四处搜索了一下,每个人使用键的建议似乎都不起作用,因为它似乎只得到祖父母范围内的唯一值,而不是父母范围内的值。

这就是我的

<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

您非常接近密钥方法,诀窍是您需要将父节点的标识作为分组密钥的一部分:

<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"等的键值。


编辑:在你的评论中,你说"在我的实际数据中,子节点不是父节点的直接子节点。父节点和子节点之间有两个级别,例如parent/./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的目标元素的最近祖先)

相关内容

  • 没有找到相关文章

最新更新