我有XML文档
<Contracts>
<Contract>
<F1>key1</F1>
<F2>2345</F2>
<F3>val</F3>
<F4>dal</F4>
</Contract>
<Contract>
<F1>key1</F1>
<F2>34562</F2>
<F3>val</F3>
<F4>dal</F4>
</Contract>
<Contract>
<F1>key2</F1>
<F2>416235</F2>
<F3>val</F3>
<F4>sal</F4>
</Contract>
<Contract>
<F1>key2</F1>
<F2>416235</F2>
<F3>val</F3>
<F4>sal</F4>
</Contract>
<Contract>
<F1>key2</F1>
<F2>41575</F2>
<F3>val</F3>
<F4>bal</F4>
</Contract>
</Contracts>
我需要按Contracts/Contract/F1
(key1,key2)对这些合同进行分组,以获得此结果:
<Contracts>
<Set>
<Contract>
<F1>key1</F1>
<F2>2345</F2>
<F3>val</F3>
<F4>dal</F4>
</Contract>
<Contract>
<F1>key1</F1>
<F2>34562</F2>
<F3>val</F3>
<F4>dal</F4>
</Contract>
<Set>
<Set>
<Contract>
<F1>key2</F1>
<F2>416235</F2>
<F3>val</F3>
<F4>sal</F4>
</Contract>
<Contract>
<F1>key2</F1>
<F2>416235</F2>
<F3>val</F3>
<F4>sal</F4>
</Contract>
<Contract>
<F1>key2</F1>
<F2>416235</F2>
<F3>val</F3>
<F4>sal</F4>
</Contract>
</Set>
</Contracts>
如何使用XSLT进行操作?
答案 0 :(得分:4)
<强>予。 XSLT 1.0解决方案(Muenchian分组,没有xsl:for-each
):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kContrByF1" match="Contract" use="F1"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"Contract[not(generate-id()
=
generate-id(key('kContrByF1', F1)[1])
)
]"/>
<xsl:template match="Contract">
<Contract>
<Set>
<xsl:copy-of select="key('kContrByF1', F1)"/>
</Set>
</Contract>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档:
<Contracts>
<Contract>
<F1>key1</F1>
<F2>2345</F2>
<F3>val</F3>
<F4>dal</F4>
</Contract>
<Contract>
<F1>key1</F1>
<F2>34562</F2>
<F3>val</F3>
<F4>dal</F4>
</Contract>
<Contract>
<F1>key2</F1>
<F2>416235</F2>
<F3>val</F3>
<F4>sal</F4>
</Contract>
<Contract>
<F1>key2</F1>
<F2>416235</F2>
<F3>val</F3>
<F4>sal</F4>
</Contract>
<Contract>
<F1>key2</F1>
<F2>41575</F2>
<F3>val</F3>
<F4>bal</F4>
</Contract>
</Contracts>
产生了想要的正确结果:
<Contracts>
<Contract>
<Set>
<Contract>
<F1>key1</F1>
<F2>2345</F2>
<F3>val</F3>
<F4>dal</F4>
</Contract>
<Contract>
<F1>key1</F1>
<F2>34562</F2>
<F3>val</F3>
<F4>dal</F4>
</Contract>
</Set>
</Contract>
<Contract>
<Set>
<Contract>
<F1>key2</F1>
<F2>416235</F2>
<F3>val</F3>
<F4>sal</F4>
</Contract>
<Contract>
<F1>key2</F1>
<F2>416235</F2>
<F3>val</F3>
<F4>sal</F4>
</Contract>
<Contract>
<F1>key2</F1>
<F2>41575</F2>
<F3>val</F3>
<F4>bal</F4>
</Contract>
</Set>
</Contract>
</Contracts>
<强> II。 XSLT 2.0解决方案:
<xsl:template match="/*">
<Contracts>
<xsl:for-each-group select="Contract" group-by="F1">
<Contract>
<Set>
<xsl:sequence select="current-group()"/>
</Set>
</Contract>
</xsl:for-each-group>
</Contracts>
</xsl:template>
</xsl:stylesheet>
同样,当在同一个XML文档(上面)上应用此转换时,会产生相同的正确结果。
请注意:
使用xsl:for-each-group
指令。
使用current-group()
功能。
答案 1 :(得分:1)
使用XSL密钥和Muenchian分组。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kContract" match="Contract" use="F1" />
<xsl:template match="Contracts">
<xsl:copy>
<xsl:for-each select="
Contract[
generate-id() = generate-id(key('kContract', F1)[1])
]
">
<Set>
<xsl:copy-of select="key('kContract', F1)" />
</Set>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
此样式表可准确生成所需的输出。