我有一个场景,其中XML文档包含一些重复的节点。我想摆脱所有这样的节点。 请注意,这是不“ 删除重复项 ”。我想完全删除那些多次出现的节点的所有条目。
实施例 我的XML
<ReadUserOBSResponse>
<UserOBS>
<OBSObjectId>1510</OBSObjectId>
<UserObjectId>443</UserObjectId>
</UserOBS>
<UserOBS>
<OBSObjectId>540</OBSObjectId>
<UserObjectId>514</UserObjectId>
</UserOBS>
<UserOBS>
<OBSObjectId>1521</OBSObjectId>
<UserObjectId>514</UserObjectId>
</UserOBS>
<UserOBS>
<OBSObjectId>547</OBSObjectId>
<UserObjectId>544</UserObjectId>
</UserOBS>
</ReadUserOBSResponse>
所需输出:我想用UserObjectId 514
删除这两个条目<ReadUserOBSResponse>
<UserOBS>
<OBSObjectId>1510</OBSObjectId>
<UserObjectId>443</UserObjectId>
</UserOBS>
<UserOBS>
<OBSObjectId>547</OBSObjectId>
<UserObjectId>544</UserObjectId>
</UserOBS>
</ReadUserOBSResponse>
我做过一些事情,但它没有用。我的想法是用UserObjectId作为当前值来计算节点,将其放在xsl:if
中,然后打印节点。
但我不确定如何编写这个片段。
答案 0 :(得分:2)
这将满足您的需求。
它有一个UserOBS
元素的模板,用于检查其父级中是否只有一个UserOBS
子级具有UserObjectId
的相同值。如果是这样,整个节点将被复制到输出。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/ReadUserOBSResponse">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="UserOBS">
<xsl:if test="count(../UserOBS[UserObjectId = current()/UserObjectId]) = 1">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
<强>输出强>
<?xml version="1.0" encoding="utf-8"?>
<ReadUserOBSResponse>
<UserOBS>
<OBSObjectId>1510</OBSObjectId>
<UserObjectId>443</UserObjectId>
</UserOBS>
<UserOBS>
<OBSObjectId>547</OBSObjectId>
<UserObjectId>544</UserObjectId>
</UserOBS>
</ReadUserOBSResponse>
答案 1 :(得分:2)
这是一种使用密钥的非常有效(简洁)的方法:
<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="kUOId" match="UserOBS" use="UserObjectId" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="UserOBS[key('kUOId', UserObjectId)[2]]" />
</xsl:stylesheet>
在样本输入上运行时,结果为:
<ReadUserOBSResponse>
<UserOBS>
<OBSObjectId>1510</OBSObjectId>
<UserObjectId>443</UserObjectId>
</UserOBS>
<UserOBS>
<OBSObjectId>547</OBSObjectId>
<UserObjectId>544</UserObjectId>
</UserOBS>
</ReadUserOBSResponse>
答案 2 :(得分:1)
XSLT 2.0中更简单:
<xsl:for-each-group select="UserObs" group-by="UserObjectId">
<xsl:copy-of select="current-group()[last()=1]"/>
</xsl:for-each-group>