我在使用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文件作为结果!!
如何去掉重复的节点()?
我试了所有的方法都没有结果:(
我试过了使用xslt删除xml中的重复项转换以删除重复和复制休息使用XSLT删除连续的重复项XSLT 1.0 textlist到单个元素和重复删除
……
我该怎么做才能得到这个结果?
<?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>
谢谢
解决方案非常简单(没有命名模板和不使用xsl:call-template
,只有两个模板,完全"push style"):
<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>
这里的问题是您的模板匹配Mappings
并试图排除以下重复的Mappings
元素,但没有。
无论哪种情况,following::
和preceding::
都不是在XSLT中选择不同值的好方法。相反,您应该使用Muenchian分组:
<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>