Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XSL将XML转换为XML的问题_Xml_Xslt - Fatal编程技术网

使用XSL将XML转换为XML的问题

使用XSL将XML转换为XML的问题,xml,xslt,Xml,Xslt,我想使用XSL将一个XML文件转换成另一个具有不同结构的XML文件,我对XSL有点陌生。XML的输入部分如下所示: <set> <object> Value </object> <name> Value </name> <tag> <event> Value </event> <group> Value

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

如果您的xslt处理器支持exslt,则可以使用set:distinct来循环不同的事件和具有该事件的不同组。我用xsltproc测试了以下内容,但它们应该可以在任何支持exslt:function的处理器中工作。请参阅:

请注意,set:distinct的实现中有一个bug,我在这里为您修复了这个bug

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>

同样地,和的值将被转换为并请使您的输入XML格式正确,因为它不是。另外,问一个关于真实代码的问题,而不是你刚刚编出来的东西,会更有用。通常,实际问题的一些小细节没有正确地再现在虚构的样本中,这会导致你中途改变问题,这会导致其他人在一个不完整的问题上浪费时间。我只是说,如何导入支持exslt的处理器?或者,如果处理器不支持exslt,我该怎么办?您使用的是哪个处理器?可以!我设法导入exslt,但出现了另一个问题。。。表示函数“set:distinct”失败…->System.ArgumentNullException:值不能为null。