使用xslt在xml中进行多重排序

时间:2017-05-21 22:05:18

标签: php xml xslt-1.0

我试图对两个xml文件进行排序以便将它们与winmerge进行比较,但是当我设法对节点进行排序但我还需要对具有相同名称的多个属性进行排序时,我遇到了问题。

这是我的xml:

<node>
  <location>A</location>
  <title>folder in A</title>
  <acl group="group_4" permissions="111111111"/>
  <acl group="group_2" permissions="110000000"/>
  <acl group="group_3" permissions="110000000"/>
  <acl group="group_1" permissions="110000000"/>
</node>
<node>
  <location>A</location>
  <title>Another folder in A</title>
  <acl group="group_1" permissions="110000000"/>
  <acl group="group_3" permissions="111111111"/>
  <acl group="group_2" permissions="110000000"/>
</node>

我的xsl看起来像这样:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" encoding="UTF-8" />
  <xsl:template match="/">
    <xsl:for-each select="import/node">
      <xsl:sort select="location" data-type="text" order="ascending"/>
      <xsl:sort select="title[not(@clear)]" data-type="text" order="ascending"/>
      <xsl:sort select="@group" data-type="text" order="ascending"/>
      <node>
        <xsl:copy-of select="location"/>
        <xsl:copy-of select="title[not(@clear)]"/>
        <xsl:copy-of select="acl[not(@basegroup) and not(@baseowner) and not(@standard)]"/>
      </node>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

我得到了这个结果:

<node>
  <location>A</location>
  <title>Another folder in A</title>
  <acl group="group_1" permissions="110000000"/>
  <acl group="group_3" permissions="111111111"/>
  <acl group="group_2" permissions="110000000"/>
</node>
<node>
  <location>A</location>
  <title>folder in A</title>
  <acl group="group_4" permissions="111111111"/>
  <acl group="group_2" permissions="110000000"/>
  <acl group="group_3" permissions="110000000"/>
  <acl group="group_1" permissions="110000000"/>
</node>

而不是这一个:

<node>
  <location>A</location>
  <title>Another folder in A</title>
  <acl group="group_1" permissions="110000000"/>
  <acl group="group_2" permissions="110000000"/>
  <acl group="group_3" permissions="111111111"/>
</node>
<node>
  <location>A</location>
  <title>folder in A</title>
  <acl group="group_1" permissions="110000000"/>
  <acl group="group_2" permissions="110000000"/>
  <acl group="group_3" permissions="110000000"/>
  <acl group="group_4" permissions="111111111"/>
</node>

我已经检查过类似的帖子,但没有任何效果。提前致谢。最好的问候。

1 个答案:

答案 0 :(得分:0)

您需要在acl(或xsl:for-each)指令中单独对xsl:apply-templates元素进行排序,例如:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8" />

<xsl:template match="/import">
    <xsl:for-each select="node">
        <xsl:sort select="location" data-type="text" order="ascending"/>
        <xsl:sort select="title" data-type="text" order="ascending"/>
        <node>
            <xsl:copy-of select="location | title"/>
            <xsl:for-each select="acl">
                <xsl:sort select="@group" data-type="text" order="ascending"/>
                <xsl:copy-of select="."/>
            </xsl:for-each> 
        </node>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>