【问题标题】:XSLT checking duplicate valuesXSLT 检查重复值
【发布时间】:2014-01-23 22:31:13
【问题描述】:

我有一个这样的传入 XML:

<comm>
 <source id ="1">TV</source>
 <source id ="2">Radio</source>
 <source id ="3">TV</source>
 <source id ="4">Computer</source>
</comm>

我需要一个 XSLT 来制作像这样的输出 XML:

<comm>
 <type id ="1">TV</source>
 <type id ="2">Radio</source>
 <type id ="4">Computer</source>
</comm>

基本上我希望 XSLT 遍历每个 &lt;source&gt; 元素并创建一个 &lt;type&gt; 元素。但是如果&lt;type&gt; 元素的值已经存在,XSLT 将跳过创建该元素。 例如,如果您查看传入的 XML,则“TV”值出现两次;所以 XSLT 只会用 TV 值创建元素一次。

我很难弄清楚这一点。我正在使用 XSLT 2.0。

我尝试通过动态更新变量然后删除重复值来做到这一点。但是 XSLT 不能改变变量。

【问题讨论】:

标签: xml xslt


【解决方案1】:

这在 XSLT 2.0 中非常简单,使用 xsl:for-each-group,尽管您只需要选择每个组中的第一个元素。

您正在通过文本值检查 source 元素,所以您需要做的就是这个

<xsl:for-each-group select="source" group-by="text()">

而将 source 更改为 type 只是通过一个简单的模板

<xsl:template match="source">
   <type>
        <xsl:apply-templates select="@*|node()"/>
   </type>
</xsl:template>

试试这个 XSLT

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

   <xsl:template match="/*">
        <xsl:copy>
           <xsl:for-each-group select="source" group-by="text()">
                <xsl:apply-templates select="."/>
           </xsl:for-each-group>
         </xsl:copy>
    </xsl:template>

    <xsl:template match="source">
        <type>
            <xsl:apply-templates select="@*|node()"/>
        </type>
    </xsl:template>

   <xsl:template match="@*|node()">
        <xsl:copy>
           <xsl:apply-templates select="@*|node()"/>
         </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

请注意使用identity template 来复制现有元素。

阅读 http://www.xml.com/lpt/a/1314 以获取有关 xsl:for-each-group 的大量帮助信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 2017-04-20
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多