我是XSLT的新手,在修改xml方面遇到了问题。
输入XML是:
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<dictionary>
<label>A</label>
<brand>top</brand>
<color>black</color>
</dictionary>
<dictionary>
<label>B</label>
<brand>lower</brand>
<color>brown</color>
</dictionary>
<dictionary>
<label>A</label>
<brand>lower</brand>
<color>yello</color>
</dictionary>
<dictionary>
<label>C</label>
<brand>middle</brand>
<color>orange</color>
</dictionary>
<dictionary>
<label>B</label>
<brand>top</brand>
<color>blue</color>
</dictionary>
<dictionary>
<label>D</label>
<brand>mid</brand>
<color>green</color>
</dictionary>
<dictionary>
<label>A</label>
<brand>mid</brand>
<color>yello</color>
</dictionary>
</xml>
它包含一些将A作为子元素之一的元素。我想删除包含重复项的字典节点。此外,虽然它删除了重复项,但它应该只删除包含!= lower
的重复节点预期输出为:
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<dictionary>
<label>B</label>
<brand>lower</brand>
<color>brown</color>
</dictionary>
<dictionary>
<label>A</label>
<brand>lower</brand>
<color>yello</color>
</dictionary>
<dictionary>
<label>C</label>
<brand>middle</brand>
<color>orange</color>
</dictionary>
<dictionary>
<label>D</label>
<brand>mid</brand>
<color>green</color>
</dictionary>
</xml>
在互联网上,我找到了一个基于元素值删除重复节点的xsl。删除重复节点的xsl是:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="LABEL" match="dictionary" use="label"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="dictionary[not(generate-id() = generate-id(key('LABEL', label)[1]))]" />
</xsl:stylesheet>
答案 0 :(得分:0)
你的描述“当它删除重复项时,它应该只删除同样包含!= lower的重复节点”对我来说还不清楚,我试图用XSLT 2.0实现它,如下所示:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="xml">
<xsl:copy>
<xsl:for-each-group select="dictionary" group-by="label">
<xsl:copy-of select="if (count(current-group()) eq 1)
then .
else current-group()[contains(brand, 'lower')]"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
转换输入
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<dictionary>
<label>A</label>
<brand>top</brand>
<color>black</color>
</dictionary>
<dictionary>
<label>B</label>
<brand>lower</brand>
<color>brown</color>
</dictionary>
<dictionary>
<label>A</label>
<brand>lower</brand>
<color>yello</color>
</dictionary>
<dictionary>
<label>C</label>
<brand>middle</brand>
<color>orange</color>
</dictionary>
<dictionary>
<label>B</label>
<brand>top</brand>
<color>blue</color>
</dictionary>
<dictionary>
<label>D</label>
<brand>mid</brand>
<color>green</color>
</dictionary>
<dictionary>
<label>A</label>
<brand>mid</brand>
<color>yello</color>
</dictionary>
</xml>
进入以下结果:
<xml>
<dictionary>
<label>A</label>
<brand>lower</brand>
<color>yello</color>
</dictionary>
<dictionary>
<label>B</label>
<brand>lower</brand>
<color>brown</color>
</dictionary>
<dictionary>
<label>C</label>
<brand>middle</brand>
<color>orange</color>
</dictionary>
<dictionary>
<label>D</label>
<brand>mid</brand>
<color>green</color>
</dictionary>
</xml>
dictionary
子元素值和每个组的样式表组label
元素输出组中的单个元素(如果只有一个)或输出组中的那些元素brand
子元素值包含lower
。
根据评论中的要求,我使用Muenchian grouping而不是for-each-group
添加了XSLT 1.0样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="by-label" match="dictionary" use="label"/>
<xsl:template match="xml">
<xsl:copy>
<xsl:for-each select="dictionary[generate-id() = generate-id(key('by-label', label)[1])]">
<xsl:variable name="current-group" select="key('by-label', label)"/>
<xsl:choose>
<xsl:when test="count($current-group) = 1">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$current-group[brand = 'lower']"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>