2009-12-17 130 views
2

我需要通过标记名称和属性对XML进行排序。 是否有可能使用DOM?排序XML文件

我需要一个排序的XML文件不是HTML的结果。

例如:

<books> 
    <book id='1'> 
     <name value='N1'/> 
     <author value='A1'/> 
    </book> 
    <book id='3'> 
     <name value='N3'/> 
     <author value='A3'/> 
    </book> 
    <book id='2'> 
     <author value='A2'/> 
     <name value='N2'/> 
    </book> 
</books> 

我希望sortXML

<books> 
    <book id='1'> 
     <author value='A1'/> 
     <name value='N1'/>  
    </book> 
    <book id='2'> 
     <author value='A2'/> 
     <name value='N2'/> 
    </book> 
    <book id='3'> 
     <author value='A3'/> 
     <name value='N3'/>  
    </book> 
</books> 

XML被标签名称进行排序,然后通过ID

+2

请原谅我的无知,但为什么要对XML进行排序?依靠元素的顺序在我对XML的理解上是不明智的。很高兴被纠正,但:) – 2009-12-17 08:43:22

+1

@Tom Duckering:为了显示的目的,我猜? – Vinz 2009-12-17 08:57:23

回答

3

你( 'ID')后获得可以编写一个XSL,使用sort-element对数据进行排序,并将XML文档转换为它,如果你的DOM实现支持XSL转换。

或者,您可以将所有元素提取到数组并实现排序算法,例如, bubble sort,对数组的元素进行排序。

或者,如果您使用.Net DOM,则可以使用排序XPath查询。 XPath不支持自行排序,但.Net实现提供了XPathExpression.AddSort method

+0

伟大的回应(总体).. +1 – 2009-12-28 08:18:40

1

用java:

  • 在所有的元素下的“书”“书”创造的“元素”
  • 循环列表,并将其添加到列表中
  • 卸下所有的“书”从父 '图书'
  • 排序列表使用自定义Comparator<Element>

    比较<元> { INT的compareTo(元一个,元件b) { /*比较A /作者和B /作者*/ 值}在列表 }

  • 遍历所有元素,并插入回'图书'

使用XSLT:

看到的xsl:for-each和xsl:sort

1

我想补充的XSL苏由Vinz拥塞:

<?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" indent="yes"/> 

    <xsl:template match="books"> 
     <books> 
      <xsl:apply-templates select="book"> 
       <xsl:sort select="@id" data-type="number" order="ascending" /> 
      </xsl:apply-templates> 
     </books> 
    </xsl:template> 

    <xsl:template match="book"> 
     <book> 
      <xsl:attribute name="id"> 
       <xsl:value-of select="@id"/> 
      </xsl:attribute> 
      <xsl:apply-templates> 
       <xsl:sort select="local-name()" data-type="text" order="ascending" /> 
      </xsl:apply-templates> 
     </book> 
    </xsl:template> 

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