我是xslt的新手,并且遇到了一个尴尬的问题,我花了很多时间才解决但无法得出结论。提前感谢您的帮助。
我有一个像这样的xml文档:
<root>
<ELEMENT id="1" >
<CHILD name="aaa">
<EMPLOYEE>Mark</EMPLOYEE>
<EMPLOYEE>John</EMPLOYEE>
</CHILD>
<CHILD name="bbb">
<EMPLOYEE>Tom</EMPLOYEE>
</CHILD>
</ELEMENT>
<ELEMENT id="2" >
<CHILD name="aaa">
<EMPLOYEE>leo</EMPLOYEE>
<EMPLOYEE>Jason</EMPLOYEE>
</CHILD>
</ELEMENT>
<ELEMENT id="1" >
<CHILD name="aaa">
<EMPLOYEE>Tim</EMPLOYEE>
</CHILD>
</ELEMENT>
</root>
我尝试做的是收集“EMPLOYEE”同时具有相同的“ELEMENT”ID和“CHILD”名称并删除重复的“ELEMENT”和“CHILD”。
我的意思是我只需要一个只有一个但所有员工都属于id = 1 name = aaa。生成的文件应如下所示:
<root>
<ELEMENT id="1" >
<CHILD name="aaa">
<EMPLOYEE>Mark</EMPLOYEE>
<EMPLOYEE>John</EMPLOYEE>
<EMPLOYEE>Tim</EMPLOYEE>
</CHILD>
<CHILD name="bbb">
<EMPLOYEE>Tom</EMPLOYEE>
</CHILD>
</ELEMENT>
<ELEMENT id="2" >
<CHILD name="aaa">
<EMPLOYEE>leo</EMPLOYEE>
<EMPLOYEE>Jason</EMPLOYEE>
</CHILD>
</ELEMENT>
</root>
我的xslt代码应该如何?我需要为每个循环迭代一次,还是应该应用递归模板?
很多tnx
非常感谢你的有用答案。它远远超出了我可以伸出的点。 但是,代码会删除一些不应删除的CHILD节点。
我尝试了一个更复杂的xml:
<ROOT>
<ELEMENT id="1" >
<CHILD name="aaa">
<EMPLOYEE>
asdf
</EMPLOYEE>
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
<CHILD name="bbb">
<EMPLOYEE>
adsf
</EMPLOYEE>
</CHILD>
</ELEMENT>
<ELEMENT id="1" >
<CHILD name="aaa">
<EMPLOYEE>
asdf
</EMPLOYEE>
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
<CHILD name="ccc">
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
</ELEMENT>
<ELEMENT id="2" >
<CHILD name="ddd">
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
<CHILD name="eee">
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
</ELEMENT>
<ELEMENT id="3" >
<CHILD name="xxx">
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
<CHILD name="yyy">
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
</ELEMENT>
<ELEMENT id="4" >
<CHILD name="ddd">
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
<CHILD name="aaa">
<EMPLOYEE>
adsf
</EMPLOYEE>
</CHILD>
</ELEMENT>
<ELEMENT id="3" >
<CHILD name="xxx">
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
<CHILD name="aaa">
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
</ELEMENT>
<ELEMENT id="1" >
<CHILD name="aaa">
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
<CHILD name="bbb">
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
</ELEMENT>
<ELEMENT id="2" >
<CHILD name="ddd">
<EMPLOYEE>
asdf
</EMPLOYEE>
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
<CHILD name="aaa">
<EMPLOYEE>
asdf
</EMPLOYEE>
</CHILD>
</ELEMENT>
</ROOT>
答案 0 :(得分:1)
此转化:
<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="kElemById" match="ELEMENT" use="@id"/>
<xsl:key name="kChildByNameAndParentId"
match="CHILD" use="concat(../@id, '+', @name)"/>
<xsl:key name="kEmplByAnc" match="EMPLOYEE"
use="concat(../../@id, '+', ../@name)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"ELEMENT
[generate-id()
=
generate-id(key('kElemById', @id)[1])
]
">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select=
"../ELEMENT/CHILD
[generate-id()
=
generate-id(key('kChildByNameAndParentId',
concat(current()/@id,
'+',
@name
)
)[1]
)
]
"/>
</xsl:copy>
</xsl:template>
<xsl:template match="CHILD">
<xsl:copy>
<xsl:apply-templates select=
"@*
|
key('kEmplByAnc', concat(../@id, '+', @name))"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ELEMENT"/>
</xsl:stylesheet>
应用于提供的XML文档:
<root>
<ELEMENT id="1" >
<CHILD name="aaa">
<EMPLOYEE>Mark</EMPLOYEE>
<EMPLOYEE>John</EMPLOYEE>
</CHILD>
<CHILD name="bbb">
<EMPLOYEE>Tom</EMPLOYEE>
</CHILD>
</ELEMENT>
<ELEMENT id="2" >
<CHILD name="aaa">
<EMPLOYEE>leo</EMPLOYEE>
<EMPLOYEE>Jason</EMPLOYEE>
</CHILD>
</ELEMENT>
<ELEMENT id="1" >
<CHILD name="aaa">
<EMPLOYEE>Tim</EMPLOYEE>
</CHILD>
</ELEMENT>
</root>
生成想要的正确结果:
<root>
<ELEMENT id="1">
<CHILD name="aaa">
<EMPLOYEE>Mark</EMPLOYEE>
<EMPLOYEE>John</EMPLOYEE>
<EMPLOYEE>Tim</EMPLOYEE>
</CHILD>
<CHILD name="bbb">
<EMPLOYEE>Tom</EMPLOYEE>
</CHILD>
</ELEMENT>
<ELEMENT id="2">
<CHILD name="aaa">
<EMPLOYEE>leo</EMPLOYEE>
<EMPLOYEE>Jason</EMPLOYEE>
</CHILD>
</ELEMENT>
</root>
解释:正确使用 Muenchian method for grouping 和 keys 。