如何从节点集中生成唯一的节点名称?

时间:2019-06-25 15:26:52

标签: xml xslt xslt-1.0

我有这个旧的节点集,它本质上是一个发货时间表:

<destinations>
    <voyage>
        <entry>
            <port>
                <item>Zeebrügge</item>
            </port>
        </entry>
        <entry>
            <port>
                <item>Bremerhaven</item>
            </port>
        </entry>
    </voyage>
    <voyage>
        <entry>
            <port>
                <item>Bremerhaven</item>
            </port>
        </entry>
        <entry>
            <port>
                <item>Zeebrügge</item>
            </port>
        </entry>
        <entry>
            <port>
                <item>Vigo</item>
            </port>
        </entry>
    </voyage>
    <voyage>
        <entry>
            <port>
                <item>Zeebrügge</item>
            </port>
        </entry>
    </voyage>
    <voyage>
        <entry>
            <port>
                <item>Bremerhaven</item>
            </port>
        </entry>
    </voyage>
</destinations>

是否可以从该节点集中生成唯一 ports的列表?

所以结果将是这样的:

<result>
   <item>Zeebrügge</item>
   <item>Bremerhaven</item>
   <item>Vigo</item>
</result>

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

您可以在XSLT 1.0中使用一种称为Muenchian Grouping的技术(因为这涉及获取每个不同值的第一个元素以获取“组”)。

首先定义如下键:

<xsl:key name="items" match="item" use="." />

要获取不同的项目,请执行此操作。...

<xsl:copy-of select="//item[generate-id() = generate-id(key('items', .)[1])]" />

尝试使用此XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" />

  <xsl:key name="items" match="item" use="." />

  <xsl:template match="/">
    <result>
      <xsl:copy-of select="//item[generate-id() = generate-id(key('items', .)[1])]" />
    </result>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

如果使用XSLT 2.0,也可以使用此功能

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output indent="yes"></xsl:output>
<xsl:template match="destinations">
    <result>
    <xsl:for-each-group select="//item" group-by="distinct-values(.)">
        <xsl:copy><xsl:value-of select="."/></xsl:copy>
    </xsl:for-each-group>
    </result>
</xsl:template>