我有一个像下面的xml
<XYZ>
<Name>abc</Name>
<Year>1984</Year>
<Model>qwe</Model>
<Name>abc</Name>
<Year>1987</Year>
<Model>qwe</Model>
<Name>qweqr</Name>
<Year>1977</Year>
<Model>tryet</Model>
</XYZ>
需要转换为
<XYZ>
<Name>abc</Name>
<Year>1984</Year>
<Year>1987</Year>
<Model>qwe</Model>
<Name>qweqr</Name>
<Year>1977</Year>
<Model>tryet</Model>
</XYZ>
这里名称可以被视为关键
答案 0 :(得分:0)
使用XSLT 1.0,可以使用Muenchian Grouping和以下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])]">
个节点后的唯一{
}
model
由于使用Muenchian方法对Stackoverflow进行XSLT分组已经有很多答案,我只是推荐Jeni Tennison http://www.jenitennison.com/xslt/grouping/muenchian.xml在本文中的详细解释。
作为XSLT分组的附加参考,您可以查看http://www.dpawson.co.uk/xsl/sect2/N4486.html
更新:根据评论建议,如果不同name
值的重复<?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>
值,则无法使用此功能。调整后的XSLT
name
适用于OP中提供的示例XML以及评论中建议的示例XML - 仅model
个唯一name
值,可选的多年和model
的唯一name
值,但也可以为不同的{{1}}列出相同的{{1}}。
答案 1 :(得分:0)
我认为您可以使用此样式表,该样式表使用键选择Year
和Model
(根据其名称对模型进行分组,然后根据其值进行分组)基于其前面的{{1} (分组名称后):
Name