我有一个xml文件,如下所示,预期输出应该只有基于recordNumber第一次出现的元素 Xml文件如下: -
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
<recordNumber>100</recordNumber>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<year>1988</year>
<recordNumber>101</recordNumber>
</cd>
<cd>
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<year>1982</year>
<recordNumber>102</recordNumber>
</cd>
<cd>
<title>Still got the blues</title>
<artist>Gary Moore</artist>
<year>1990</year>
<recordNumber>100</recordNumber>
</cd>
<cd>
<title>Eros</title>
<artist>Eros Ramazzotti</artist>
<year>1997</year>
<recordNumber>100</recordNumber>
</cd>
<cd>
<title>One night only</title>
<artist>Bee Gees</artist>
<year>1998</year>
<recordNumber>101</recordNumber>
</cd>
预期输出: - 预期输出应该只包含基于recordNumber第一次出现的元素
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
<recordNumber>100</recordNumber>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<year>1988</year>
<recordNumber>101</recordNumber>
</cd>
<cd>
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<year>1982</year>
<recordNumber>102</recordNumber>
</cd>
答案 0 :(得分:1)
更好的解决方案是使用XSLT 2.0分组:
<xsl:for-each-group select="cd" group-by="recordNumber">
<xsl:copy-of select="current-group()[1]"/>
</xsl:for-each-group>
答案 1 :(得分:0)
虽然这种搜索非常密集,但它完成了这项工作:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="cd[count(preceding-sibling::cd[recordNumber = current()/recordNumber]) > 0]" />
</xsl:stylesheet>
答案 2 :(得分:0)
首先,您显示的输入XML格式不正确。它缺少结束</catalog>
标记。
您的要求非常简单。它可以通过两个模板来解决,一个执行身份转换,另一个将cd
个元素保留在输出中,如果它们前面有另一个cd
元素相同的recordNumber
元素。
<强>样式表强>
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="cd[preceding::cd[recordNumber = current()/recordNumber]]"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:transform>
XML输出
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
<recordNumber>100</recordNumber>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<year>1988</year>
<recordNumber>101</recordNumber>
</cd>
<cd>
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<year>1982</year>
<recordNumber>102</recordNumber>
</cd>
</catalog>
顺便说一下:
for-each-group
)。