2010-06-05 61 views
1

我想通過多個屬性(首先由T然後由L)對「自由格式」XML文件進行排序。所述XML是有點複雜的和,如下所示,在結構:通過多個屬性排序XML文件

<?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" L="1" T="2" /> 
     <a:input FIELDNUMBER="02" INDEX="4" L="200" T="1" /> 
    </a:fieldset> 
    <a:fieldset FIELD="b" FIELDNAME="FieldSet1"> 
     <a:select1 FIELDNUMBER="03" T="3" L="1" /> 
     <a:input FIELDNUMBER="04" INDEX="7" T="4" L="200" /> 
     <a:fieldset FIELD="c" FIELDNAME="FieldSet1"> 
     <a:input FIELDNUMBER="05" T="10" INDEX="6" L="400" /> 
     <a:input FIELDNUMBER="06" T="8" INDEX="8" L="200" /> 
     </a:fieldset> 
    </a:fieldset> 
    <a:input FIELDNUMBER="08" INDEX="3" L="3" T="5" /> 
    <a:input FIELDNUMBER="09" INDEX="2" L="2" T="5" /> 
    </a:form> 
</wb> 

PS:

  1. 根元素是WB和該後面總是跟隨一個:形式
  2. 的L和T總是在命名空間a中有一個標籤的元素中找到,唯一的例外是:沒有L和T的字段集a:字段集可以包含另一個命名空間a的多個子項:字段集
  3. 排序字段集中的子元素時,這些子元素需要保持連接到其當前父元素。

輸出的結果應該是以下幾點:

<?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:input FIELDNUMBER="02" INDEX="4" L="200" T="1" /> 
     <a:select1 FIELDNUMBER="01" L="1" T="2" /> 
    </a:fieldset> 
    <a:fieldset FIELD="b" FIELDNAME="FieldSet1"> 
     <a:select1 FIELDNUMBER="03" T="3" L="1" /> 
     <a:input FIELDNUMBER="04" INDEX="7" T="4" L="200" /> 
     <a:fieldset FIELD="c" FIELDNAME="FieldSet1"> 
     <a:input FIELDNUMBER="06" T="8" INDEX="8" L="200" /> 
     <a:input FIELDNUMBER="05" T="10" INDEX="6" L="400" /> 
     </a:fieldset> 
    </a:fieldset> 
    <a:input FIELDNUMBER="09" INDEX="2" L="2" T="5" /> 
    <a:input FIELDNUMBER="08" INDEX="3" L="3" T="5" /> 
    </a:form> 
</wb> 

爲了更好地理解,我們可以假設,L表示左,T表示頂部。所以,這個想法是,當我查看轉換後的XML時,我可以立即注意到哪些元素在哪些元素之前。

你對此有何看法?

+0

不清楚!提供的XML文檔的結果輸出是什麼?請編輯你的問題。 – 2010-06-05 15:10:00

+0

在a:form(或其他a:fieldset中)中對實際的a:fieldset元素進行排序的規則是什麼?對於a:表單,字段集顯示爲第一個孩子。在第二個子字段集中,字段集是最後一個子集。 – 2010-06-07 11:54:40

+0

所有東西都應該先由T再由L排序。 每個級別都應該單獨排序。所以,a:表單元素(1級的孩子w.r.t a:表單)將獨立於其他級別的孩子(2級或更高級別)進行排序。在我的例子中,忽略a:fieldset元素只有2個1級子元素(fieldnumber =「09」和fieldnumber =「08」)。然後,字段=「b」,即2 - fieldnumber =「03」和fieldnumber =「04」的fieldset的元素應該獨立於級別1排序,或者field =「c」的字段集合排序。其他節點的推理如下。 – user164701 2010-06-08 18:15:12

回答

0

試試這個:(做出一些改變,如果我沒有理解錯你的問題)

<xsl:template match="/wb"> 
    <xsl:copy> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates mode="aaa" select="."/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="*" mode="aaa"> 
    <xsl:if test="child::*[1][not(@T) or not(@L)]"> 
     <xsl:for-each select="child::*[not(@T) or not(@L)]"> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates mode="aaa" select="."/> 
     </xsl:copy> 
     </xsl:for-each> 
    </xsl:if> 
    <xsl:variable name="sorted1"> 
     <xsl:for-each select="a:*[@T and @L]"> 
     <xsl:sort select="@T" data-type="number" order="ascending"></xsl:sort> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
     </xsl:copy> 
     </xsl:for-each> 
    </xsl:variable> 
    <xsl:for-each select="msxsl:node-set($sorted1)/*[not(@T=preceding-sibling::*/@T)]"> 
     <xsl:variable name="tval" select="@T"/> 
     <xsl:for-each select="msxsl:node-set($sorted1)/*[@T=$tval]"> 
     <xsl:sort select="@L" data-type="number" order="ascending"></xsl:sort> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
     </xsl:copy> 
     </xsl:for-each> 
    </xsl:for-each> 

    <xsl:if test="not(child::*[1][not(@T) or not(@L)])"> 
     <xsl:for-each select="child::*[not(@T) or not(@L)]"> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates mode="aaa" select="."/> 
     </xsl:copy> 
     </xsl:for-each> 
    </xsl:if> 

    </xsl:template>