通过XSL对XML文件进行排序

时间:2010-05-25 18:53:37

标签: xml xslt

我有一个XML文件,我想按属性排序。该文件的结构如下所示:

<wb xmlns:cf="http://www.macromedia.com/2004/cfform">

    <a:form name="chart">  

        <a:input FIELDNUMBER="09" INDEX="2" LEFT="200" />
        <a:input FIELDNUMBER="08" INDEX="3" LEFT="200" />

        <a:fieldset FIELD="a" FIELDNAME="FieldSet1">                              
            <a:input FIELDNUMBER="02" INDEX="4" LEFT="200" />
            <a:select1  FIELDNUMBER="01" />
        </a:fieldset>

        <a:fieldset FIELD="b" FIELDNAME="FieldSet1">                              
            <a:input FIELDNUMBER="04" INDEX="7" LEFT="200" />
            <a:select1  FIELDNUMBER="03" />
            <a:fieldset FIELD="c" FIELDNAME="FieldSet1">                              
                <a:input FIELDNUMBER="06" INDEX="8" LEFT="200" />
                <a:input FIELDNUMBER="05" INDEX="6" LEFT="200" />
            </a:fieldset>
       </a:fieldset>

    </a:form>

</wb> 

我想在整个@fieldnumber中对上述XML进行排序,但同时我希望保持XML的相同结构。我已设法对其他XML文件进行排序,但它们没有这样的嵌套级别。这是否可以单独使用XSL,如果是这样,怎么办呢?

输出应如下:

<wb xmlns:cf="http://www.macromedia.com/2004/cfform">

    <a:form name="chart">  

        <a:input FIELDNUMBER="08" INDEX="3" LEFT="200" />
        <a:input FIELDNUMBER="09" INDEX="2" LEFT="200" />

        <a:fieldset FIELD="a" FIELDNAME="FieldSet1">                              
            <a:select1  FIELDNUMBER="01" />
            <a:input FIELDNUMBER="02" INDEX="4" LEFT="200" />
        </a:fieldset>

        <a:fieldset FIELD="b" FIELDNAME="FieldSet1">                              
            <a:select1  FIELDNUMBER="03" />
            <a:input FIELDNUMBER="04" INDEX="7" LEFT="200" />
            <a:fieldset FIELD="c" FIELDNAME="FieldSet1">                              
                <a:input FIELDNUMBER="05" INDEX="6" LEFT="200" />
                <a:input FIELDNUMBER="06" INDEX="8" LEFT="200" />
            </a:fieldset>
       </a:fieldset>

    </a:form>

</wb> 

作为另一个例子,如果将FIELDNUMBER 04更改为大于7的值(例如10)(假设在此示例中为10),那么具有FIELD值b的字段集的输出将变为:

        <a:fieldset FIELD="b" FIELDNAME="FieldSet1">                              
            <a:select1  FIELDNUMBER="03" />
            <a:fieldset FIELD="c" FIELDNAME="FieldSet1">                              
                <a:input FIELDNUMBER="05" INDEX="6" LEFT="200" />
                <a:input FIELDNUMBER="06" INDEX="8" LEFT="200" />
            </a:fieldset>
            <a:input FIELDNUMBER="10" INDEX="7" LEFT="200" />
       </a:fieldset>

1 个答案:

答案 0 :(得分:2)

尽管吉姆加里森指出了不一致的地方,但我试图提出符合你描述的东西:

<?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="*">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:for-each select="*">
        <xsl:sort select="@FIELDNUMBER|.//@FIELDNUMBER"/>
        <xsl:apply-templates select="." />
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

排序首先在元素的FIELDNUMBER属性上工作,或者在元素的子元素上找到的第一个FIELDNUMBER属性(如果元素本身没有)。这是输出(xmlns:a被添加到源文档中,因此它被带到输出中):

<?xml version="1.0" encoding="utf-8"?>
<wb xmlns:cf="http://www.macromedia.com/2004/cfform" xmlns:a="urn:dummy">
  <a:form name="chart">
    <a:fieldset FIELD="a" FIELDNAME="FieldSet1">
      <a:select1 FIELDNUMBER="01" />
      <a:input FIELDNUMBER="02" INDEX="4" LEFT="200" />
    </a:fieldset>
    <a:fieldset FIELD="b" FIELDNAME="FieldSet1">
      <a:select1 FIELDNUMBER="03" />
      <a:input FIELDNUMBER="04" INDEX="7" LEFT="200" />
      <a:fieldset FIELD="c" FIELDNAME="FieldSet1">
        <a:input FIELDNUMBER="05" INDEX="6" LEFT="200" />
        <a:input FIELDNUMBER="06" INDEX="8" LEFT="200" />
      </a:fieldset>
    </a:fieldset>
    <a:input FIELDNUMBER="08" INDEX="3" LEFT="200" />
    <a:input FIELDNUMBER="09" INDEX="2" LEFT="200" />
  </a:form>
</wb>