使用XSLT 1.0,这是可以做到的XML使用Muenchian分组和以下XSLT:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="names" match="Name" use="text()"/>
<xsl:key name="models" match="Model" use="text()"/>
<xsl:template match="XYZ">
<XYZ>
<xsl:for-each select="//Name[generate-id()=generate-id(key('names',text())[1])]">
<xsl:variable name="current" select="."/>
<xsl:apply-templates select="."/>
<xsl:apply-templates select="//Name[.=$current]/following-sibling::Year[1]"/>
<xsl:for-each select="//Name[.=$current]/following-sibling::Model[1]
[generate-id()=generate-id(key('models',text())[1])]">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:for-each>
</XYZ>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:transform>
结果:
<XYZ>
<Name>abc</Name>
<Year>1984</Year>
<Year>1987</Year>
<Model>qwe</Model>
<Name>qweqr</Name>
<Year>1977</Year>
<Model>tryet</Model>
</XYZ>
为Year
和Model
重复的节点被移除,因为只有唯一值在xsl:for-each
选自:
<xsl:for-each select="//Name[generate-id()=generate-id(key('names',text())[1])]">
独特Name
被复制,然后所有具有年在前Name
与目前唯一的值Name
:
<xsl:apply-templates select="//Name[.=$current]/following-sibling::Year[1]"/>
然后,对应的唯一Model
节点被复制与第二xsl:for-each
只选择唯一以下Model
节点:
<xsl:for-each select="//Name[.=$current]/following-sibling::Model[1]
[generate-id()=generate-id(key('models',text())[1])]">
由于有#2已经有很多答案为XSLT使用Muenchian法分组,我只是建议的详细解释在Jeni Tennison的文章http://www.jenitennison.com/xslt/grouping/muenchian.xml中。对于XSLT分组可以看看http://www.dpawson.co.uk/xsl/sect2/N4486.html
更新
作为附加参考:作为建议的评论,这不会在不同name
值重复model
值的情况下工作。继调整XSLT
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8 indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="names" match="Name" use="text()"/>
<xsl:template match="XYZ">
<XYZ>
<xsl:for-each select="//Name[generate-id()=generate-id(key('names',text())[1])]">
<xsl:variable name="current" select="."/>
<xsl:apply-templates select="."/>
<xsl:apply-templates select="//Name[.=$current]/following-sibling::Year[1]"/>
<xsl:for-each select="//Name[.=$current]/following-sibling::Model[1]
[not(.= preceding-sibling::Name[.=$current]
/preceding-sibling::Name[.=$current]
/following-sibling::Model)]">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:for-each>
</XYZ>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:transform>
作品在OP提供以及示例XML示例XML中的注释建议 - 只可选多岁,独特model
值唯一name
值的name
,但同样model
可以也被列为不同的name
。
XSLT的哪个版本? –
你想如何输出模型?你甚至想要模型分组? –
@ user2317758如果有帮助,请考虑通过选中答案接受答案。 –