开发者

Sorting XML file

开发者 https://www.devze.com 2022-12-14 01:50 出处:网络
I need to sort an XML by tag names and attribute. Is it possible using DOM? I need the result in a sorted XML file not HTML.

I need to sort an XML by tag names and attribute. Is it possible using DOM?

I need the result in a sorted XML file not HTML.

for example:

<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>

I expect t开发者_如何学Pythono get after sortXML ('id')

<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 is sorted by tag names then by id


You could write an XSL that sorts your data using the sort-element and transform you XML document with it, if your DOM implementation supports XSL Transformations.

Alternatively you could fetch all elements to an array and implement a sorting algorithm, e.g. bubble sort, to sort the elements of the array.

Or, if you are using the .Net DOM you could use a sorting XPath query. XPath does not support sorting by itself, but the .Net implementation provides the XPathExpression.AddSort method.


Using java:

  • create a list of 'Element'
  • loop over all the elements 'book' under 'books' and add it to the list
  • detach all the 'book' from the parent 'books'
  • sort your list using a custom Comparator<Element>

    Comparator< Element > { int compareTo(Element a,Element b) { /* compare the values of a/author and b/author */ } }

  • loop over all the Element in your list and insert it back to 'books'

Using xslt:

see xsl:for-each and xsl:sort


Just to add the xsl suggested by 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>


You can use the YAML processor mikefarah/yq to sort XML.

Version < 4.30

yq --input-format xml --output-format xml '.books.book |= (sort_by(.+id) | .. | sort_keys(.))'

Version >= 4.30

yq --input-format xml --output-format xml '.books.book |= (sort_by(.+@id) | .. | sort_keys(.))'

sort_by(.+@id) sorts the array elements. sort_keys(.) sorts the keys inside every item.

Output

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

精彩评论

暂无评论...
验证码 换一张
取 消