使用XSL问题的XML到XML

时间:2010-01-25 15:51:11

标签: xml xslt

我想使用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并根据“事件”节点对事件进行分组,然后使用相同值的“组”节点。帮助

1 个答案:

答案 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>