我想使用XSL将XML文件转换为另一个具有不同结构的XML文件,而且我是XSL的新手。 XML的输入部分如下:
<set>
<object> Value </object>
<name> Value </name>
<tag>
<event> Value </event>
<group> Value </group>
<other> Value </other>
</tag>
<object>
<object>...</object>
</set>
我希望输出为:
<set>
<event>
<group>
<object name="value">
<tag>
<other> Value </other>
</tag>
</object>
<group>
<group>...</group>
<event>...</event>
</set>
意思是说我想搜索输入xml并根据“事件”节点对事件进行分组,然后使用相同值的“组”节点。帮助
答案 0 :(得分:0)
如果您的xslt处理器支持exslt,您可以使用set:distinct来循环不同事件和具有该事件的不同组。我使用xsltproc测试了以下内容,但它们应该适用于任何支持exslt:function的处理器。见:http://www.exslt.org/func/elements/function/index.html。
请注意,我在这里修复了set:distinct发布的错误。
test.xslt:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:func="http://exslt.org/functions"
xmlns:set="http://exslt.org/sets"
extension-element-prefixes="func set">
<xsl:import href="set.distinct.function.xsl" />
<xsl:template match="set">
<set>
<xsl:variable name="set" select="."/>
<xsl:value-of select="count(object/tag/event)"/><xsl:text> </xsl:text>
<xsl:value-of select="count(set:distinct(object/tag/event))"/>
</xsl:for-each>
<xsl:for-each select="set:distinct(object/tag/event)">
<event>
<xsl:attribute name="name">
<xsl:value-of select="."/>
</xsl:attribute>
<xsl:variable name="event" select="." />
<xsl:for-each select="set:distinct($set/object/tag[event=$event]/group)">
<group>
<xsl:attribute name="name">
<xsl:value-of select="."/>
</xsl:attribute>
<xsl:variable name="group" select="." />
<xsl:apply-templates select="$set/object[tag/event=$event][tag/group=$group]" />
</group>
</xsl:for-each>
</event>
</xsl:for-each>
</set>
</xsl:template>
<xsl:template match="object">
<object name="{name}"/>
</xsl:template>
</xsl:stylesheet>
set.distinct.function.xsl:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/functions"
xmlns:set="http://exslt.org/sets"
extension-element-prefixes="exsl"
exclude-result-prefixes="set">
<exsl:function name="set:distinct">
<xsl:param name="nodes" select="/.." />
<xsl:choose>
<xsl:when test="not($nodes)">
<exsl:result select="/.." />
</xsl:when>
<xsl:otherwise>
<xsl:variable name="distinct"
select="set:distinct($nodes[position() > 1])" />
<exsl:result select="$distinct | $nodes[1][not(. = $distinct)]" />
</xsl:otherwise>
</xsl:choose>
</exsl:function>
</xsl:stylesheet>
的test.xml:
<set>
<object>
<name> Value1 </name>
<tag>
<event> Value </event>
<group> Value </group>
<other> Value </other>
</tag>
</object>
<object>
<name> Value2 </name>
<tag>
<event> Value </event>
<group> Value2 </group>
<other> Value </other>
</tag>
</object>
<object>
<name> Value3 </name>
<tag>
<event> Value </event>
<group> Value2 </group>
<other> Value </other>
</tag>
</object>
<object>
<name> Value4 </name>
<tag>
<event> Value </event>
<group> Value </group>
<other> Value </other>
</tag>
</object>
<object>
<name> Value5 </name>
<tag>
<event> Value2 </event>
<group> Value </group>
<other> Value </other>
</tag>
</object>
<object>
<name> Value6 </name>
<tag>
<event> Value2 </event>
<group> Value </group>
<other> Value </other>
</tag>
</object>
</set>