我有这个输入XML,需要用xslt
进行转换<root>
<node id="a">
<section id="a_1" method="run">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_1" method="run">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1" method="create">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_1" method="create">
<user id="b_1c">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
</section>
</node>
</root>
预期产出:
<root>
<node id="a">
<section id="a_1">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1" method="create">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
</section>
</node>
</root>
哪个节点将被删除无关紧要,只要它具有相同的元素名称,id和方法,其中一个将被删除。 知道xsl是什么样的吗?
注意:元素名称可以是任何不必要的,并且在整个文件中有多个元素名称;只要它具有相同的元素名称,id和属性(例如方法=创建),其中一个将被删除。
非常感谢。 干杯, 约翰
答案 0 :(得分:3)
<强>予。这是一个简短而有效的(使用密钥)XSLT 1.0转换:
<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="kElemWithAttribs" match="*[@id and @method]"
use="concat(name(), '+', @id, '+', @method)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"*[@id and @method
and
not(generate-id()
=
generate-id(key('kElemWithAttribs',
concat(name(), '+', @id, '+', @method)
)[1]
)
)
]"/>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<root>
<node id="a">
<section id="a_1" method="run">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_1" method="run">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1" method="create">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_1" method="create">
<user id="b_1c">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
</section>
</node>
</root>
产生了想要的正确结果:
<root>
<node id="a">
<section id="a_1" method="run">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1" method="create">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
</section>
</node>
</root>
<强>解释强>:
将 Muenchian method for grouping 与复合键一起使用。在这里,我们忽略(删除)不是组中第一个节点的每个节点。
<强> II。 XSLT 2.0解决方案 - 更短,效率更低:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="*"
group-by="concat(name(), '+', @id, '+', @method)">
<xsl:apply-templates select="."/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<强>解释强>:
正确使用带有group-by
属性的 xsl:for-each-group
。
答案 1 :(得分:1)
XSL文件:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="root">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="node">
<node>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</node>
</xsl:template>
<xsl:template match="section[@id = 'b_1'][1]">
<section>
<xsl:copy-of select="node()|@*"/>
</section>
</xsl:template>
<xsl:template match="section[@id != 'b_1']">
<section>
<xsl:copy-of select="node()|@*"/>
</section>
</xsl:template>
<xsl:template match="section[@id = 'b_1'][position() > 1]"/>
</xsl:stylesheet>
转型:
<root>
<node id="a">
<section id="a_1">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1" method="create">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
</section>
</node>
</root>
希望这会有所帮助。
[编辑] 在同一输入文件上试用此XSL:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*[not(@id eq preceding::*[local-name() eq local-name(.)]/@id)]">
<xsl:element name="{name()}">
<xsl:copy-of select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
,结果:
<root>
<node id="a">
<section id="a_1">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1" method="create">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_1" method="create">
<user id="b_1c">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
</section>
</node>
</root>
[/编辑]