Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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
使用XSLT对复杂XML进行排序_Xml_Sorting_Xslt - Fatal编程技术网

使用XSLT对复杂XML进行排序

使用XSLT对复杂XML进行排序,xml,sorting,xslt,Xml,Sorting,Xslt,我有一个复杂的xml结构,新的xml文件不断以这种方式创建。 我正试图把文件按字母顺序排序。 我可以对配置类型进行排序,但我还想对其中的“部分”和“参数”进行排序 XML输入 预期的XML输出 这是我的XSLT: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl

我有一个复杂的xml结构,新的xml文件不断以这种方式创建。 我正试图把文件按字母顺序排序。 我可以对配置类型进行排序,但我还想对其中的“部分”和“参数”进行排序

XML输入

预期的XML输出

这是我的XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="/">    
    <Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <xsl:apply-templates/>                          
    </Document>
</xsl:template> 
<xsl:template match="Configurations">
    <xsl:copy>
        <xsl:for-each select="Configuration" >
            <xsl:sort select="@type"/>
            <xsl:copy-of select="." /> 
            <xsl:apply-templates select="."/>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>
<xsl:template match="Configurations/Configuration/Section">
    <xsl:copy>
        <xsl:for-each select="Parameter" >
            <xsl:sort select="@name"/>
            <xsl:copy-of select="." />
        </xsl:for-each>
    </xsl:copy>         
</xsl:template> 
    <xsl:template match="Adaptors">
    <xsl:copy>
        <xsl:for-each select="Adaptor">
            <xsl:sort select="@type"/>
            <xsl:copy-of select="." />
        </xsl:for-each>     
    </xsl:copy>
</xsl:template>     
</xsl:stylesheet>

在您的尝试中,如果您仅将
应用模板
排序
一起使用,则每个使用
,然后使用
副本
应用模板
,这会导致问题,也就是说,将代码替换为

   <xsl:for-each select="Configuration" >
        <xsl:sort select="@type"/>
        <xsl:copy-of select="." /> 
        <xsl:apply-templates select="."/>
    </xsl:for-each>
使用一个模板处理所有此类元素。和附加的身份转换模板

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

进入



输出应该是什么样子?您能提供一个示例吗?显然,在同一输入上执行
复制
然后
应用模板
的代码是错误的,这个答案解决了这个问题。但是答案可以理解为建议,永远不要将
xsl:for-each
xsl:sort
一起使用。我不确定这是不是有意的,但这不是我会给出的建议。@MichaelKay,对不起,这句话的意思是介绍如何更正发布代码中的问题,而不是一般性的建议。我将尝试重写它,以明确该语句引用了问题代码中采用的方法。我对这些进行了很好的排序,但我仍然坚持对每个“配置”和“适配器”部分中的“部分”和“参数”进行排序。@skaliam,我添加了一个模板来展示如何扩展该方法,以便按
@name
对其他元素进行排序。如果你仍然有问题,那么编辑你的问题并提供一个简短但无序的样本和你想要的相应结果。@ SkAlAM,如果答案解决了你的问题,然后考虑接受它。
<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>
<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>