使用XSLT对复杂的XML进行排序

时间:2016-03-01 08:54:01

标签: xml sorting xslt

我有一个复杂的xml结构,并且这种方式不断创建新的xml文件。 我试图对文件进行排序,使其按字母顺序排列。 我可以对配置类型进行排序,但我也想对" Sections"进行排序。和"参数"内部。

XML输入

- index.html
- img2.PNG  
- folder (inside this I have img1.PNG)

预期的XML输出

<Document>
<Configurations>
    <Configuration type="TypeB">
        <Section name="SectionA">
            <Parameter name="ParameterB"/>
            <Parameter name="ParameterA"/>
        </Section>
        <Section name="TypeA">
            <Parameter name="ParameterA"/>
        </Section>
    </Configuration>
    <Configuration type="TypeA">
        <Section name="SectionA">
            <Parameter name="ParameterA"/>
        </Section>
    </Configuration>
</Configurations>
</Document>

这是我的XSLT:

<Document>
<Configurations>
<Configuration type="TypeA">
        <Section name="SectionA">
            <Parameter name="ParameterA"/>
        </Section>
    </Configuration>
    <Section name="TypeA">
            <Parameter name="ParameterA"/>
        </Section>
    <Configuration type="TypeB">
        <Section name="SectionA">
        <Parameter name="ParameterA"/>
            <Parameter name="ParameterB"/>
        </Section>
    </Configuration>
</Configurations>
</Document>

1 个答案:

答案 0 :(得分:1)

在您尝试使用for-each时使用sort,然后使用copy-ofapply-templates会导致问题,如果您只使用apply-templates sort,即替换

之类的代码
   <xsl:for-each select="Configuration" >
        <xsl:sort select="@type"/>
        <xsl:copy-of select="." /> 
        <xsl:apply-templates select="."/>
    </xsl:for-each>

<xsl:apply-templates select="Configuration">
  <xsl:sort select="@type"/>
</xsl:apply-templates>

然后你应该能够得到你想要的结果。

由于您似乎希望始终按type属性排序,我认为您可以使用例如。

<xsl:template match="*[*/@type]">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates select="*">
      <xsl:sort select="@type"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

使用一个模板处理所有这些元素。和其他身份转换模板

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

应该处理其余部分(例如带有文本内容的叶元素)。

如果您要按name属性排序其他元素,则添加模板

<xsl:template match="*[*/@name]">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates select="*">
      <xsl:sort select="@name"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

应该足够了。

以下是完整的示例:

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

<xsl:output indent="yes"/>

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="*[*/@type]">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates select="*">
      <xsl:sort select="@type"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

<xsl:template match="*[*/@name]">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates select="*">
      <xsl:sort select="@name"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

它转换

<?xml version="1.0" encoding="UTF-8"?>
<Document>
   <Adaptors>
      <Adaptor type="TypeB">
         <Section name="SectionB">
            <Parameter name="ParameterB"/>
         </Section>
         <Section name="SectionA">
            <Parameter name="ParameterA"/>
         </Section>
      </Adaptor>
      <Adaptor type="TypeA">
         <Section name="SectionB">
            <Parameter name="ParameterB"/>
         </Section>
         <Section name="SectionA">
            <Parameter name="ParameterA"/>
         </Section>
      </Adaptor>
   </Adaptors>
   <Configurations>
      <Configuration type="TypeB">
         <Section name="SectionB">
            <Parameter name="ParameterB"/>
         </Section>
         <Section name="SectionA">
            <Parameter name="ParameterA"/>
         </Section>
      </Configuration>
      <Configuration type="TypeA">
         <Section name="SectionB">
            <Parameter name="ParameterB"/>
         </Section>
         <Section name="SectionA">
            <Parameter name="ParameterA"/>
         </Section>
      </Configuration>
   </Configurations>
</Document>

进入

<Document>

   <Adaptors>
      <Adaptor type="TypeA">
         <Section name="SectionA">
            <Parameter name="ParameterA"/>
         </Section>
         <Section name="SectionB">
            <Parameter name="ParameterB"/>
         </Section>
      </Adaptor>
      <Adaptor type="TypeB">
         <Section name="SectionA">
            <Parameter name="ParameterA"/>
         </Section>
         <Section name="SectionB">
            <Parameter name="ParameterB"/>
         </Section>
      </Adaptor>
   </Adaptors>

   <Configurations>
      <Configuration type="TypeA">
         <Section name="SectionA">
            <Parameter name="ParameterA"/>
         </Section>
         <Section name="SectionB">
            <Parameter name="ParameterB"/>
         </Section>
      </Configuration>
      <Configuration type="TypeB">
         <Section name="SectionA">
            <Parameter name="ParameterA"/>
         </Section>
         <Section name="SectionB">
            <Parameter name="ParameterB"/>
         </Section>
      </Configuration>
   </Configurations>

</Document>