XSLT 1.0 - 删除重复字段

时间:2013-03-21 15:33:59

标签: xml xslt xslt-1.0

我遇到了XSLT V1.0的问题,删除了重复的节点。我有这个条目

    <?xml version="1.0" encoding="utf-8"?>
<myRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Mappings>
        <Mapping fieldName="field1" >
        </Mapping>
        <Mapping fieldName="field1">
        </Mapping>
        <Mapping fieldName="field2" >
        </Mapping>
        <Mapping fieldName="field3" >
        </Mapping>
        <Mapping fieldName="field4">
        </Mapping>
    </Mappings>
</myRoot>

我有这个XSL文件

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

    <xsl:output method="xml" encoding="utf-8" indent="yes"/>

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

    <xsl:template match="Mappings">
        <xsl:if test="not(following::Mappings[Mapping/@fieldName=current()/Mapping/@fieldName])">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:if>       
    </xsl:template>


</xsl:stylesheet>

我有相同的条目XML文件!

如何摆脱重复的节点()?

我尝试了一切,没有结果:(

我试过了 Removing duplicates in xml with xslt Transform to remove duplicate and copy rest Removing consecutive duplicates with XSLT XSLT 1.0 textlist to individual elements and duplicate removal

...

我该怎么做才能得到这个结果?

 <?xml version="1.0" encoding="utf-8"?>
    <myRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <Mappings>
            <Mapping fieldName="field1">
            </Mapping>
            <Mapping fieldName="field2" >
            </Mapping>
            <Mapping fieldName="field3" >
            </Mapping>
            <Mapping fieldName="field4">
            </Mapping>
        </Mappings>
    </myRoot>

由于

2 个答案:

答案 0 :(得分:1)

解决方案非常简单(没有命名模板,也没有使用xsl:call-template,只有两个模板,完全是“推送风格”)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kFieldNameByVal" match="@fieldName" use="."/>

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

  <xsl:template match=
   "Mapping[not(generate-id(@fieldName)
           = generate-id(key('kFieldNameByVal', @fieldName)[1]))]"/>

</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<myRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Mappings>
        <Mapping fieldName="field1" >
        </Mapping>
        <Mapping fieldName="field1">
        </Mapping>
        <Mapping fieldName="field2" >
        </Mapping>
        <Mapping fieldName="field3" >
        </Mapping>
        <Mapping fieldName="field4">
        </Mapping>
    </Mappings>
</myRoot>

产生了想要的正确结果:

<myRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Mappings>
      <Mapping fieldName="field1"/>
      <Mapping fieldName="field2"/>
      <Mapping fieldName="field3"/>
      <Mapping fieldName="field4"/>
   </Mappings>
</myRoot>

答案 1 :(得分:0)

这里的问题是您的模板与Mappings匹配并尝试排除以下重复的Mappings元素,但没有。

在任何一种情况下,following::preceding::都不是在XSLT中选择不同值的好方法。相反,您应该使用Muenchian grouping

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  <xsl:strip-space elements="*" />

  <xsl:key name="kMapping" match="Mapping" use="@fieldName"/>

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

  <xsl:template match="Mapping[generate-id() = 
                               generate-id(key('kMapping', @fieldName)[1])]">
    <xsl:call-template name="Copy" />
  </xsl:template>
  <xsl:template match="Mapping" />
</xsl:stylesheet>

在样本输入上运行时,会产生:

<myRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Mappings>
    <Mapping fieldName="field1" />
    <Mapping fieldName="field2" />
    <Mapping fieldName="field3" />
    <Mapping fieldName="field4" />
  </Mappings>
</myRoot>