简体   繁体   中英

Sort nodes in XML using DOM parser

How can I sort the XML nodes according to the tag and append in the new XML using DOM parser or can it be done using DOM parser. We've used DOM parser extensively for appending nodes into a new file but I am not able to sort the nodes.

Any help would be highly appreciated.

Input.xml

<rss version="2.0">
    <Configs>
        <Value>defaultValue</Value>
        <Config name="test1">
            <title>Title 1</title>
            <author>Author1</author>
            <value>5600</value>
            <order>02</order>
        </Config>
        <Config name="test2">
            <title>Title 2</title>
            <author>Author2</author>
            <Value>6100</Value>
            <order>01</order>
        </Config>
    </Configs>
    <Ratings>
        <body>
            <Items name="ac_object1">
                <something1>something1</something1>
                <value>someValue1</value>
                <order>02</order>
            </Items>
            <Items name="op_object2">
                <something1>something2</something1>
                <value>someValue2</value>
                <order>03</order>
            </Items>
            <Items name="vt_object3">
                <something1>something3</something1>
                <value>someValue3</value>
                <order>01</order>
            </Items>
        </body>
    </Ratings>
</rss>

Expected Output.xml

<rss version="2.0">
    <Configs>
        <Value>defaultValue</Value>
        <Config name="test2">
            <title>Title 2</title>
            <author>Author2</author>
            <Value>6100</Value>
            <order>01</order>
        </Config>
        <Config name="test1">
            <title>Title 1</title>
            <author>Author1</author>
            <value>5600</value>
            <order>02</order>
        </Config>
    </Configs>
    <Ratings>
        <body>
            <Items name="vt_object3">
                <something1>something3</something1>
                <value>someValue3</value>
                <order>01</order>
            </Items>
            <Items name="ac_object1">
                <something1>something1</something1>
                <value>someValue1</value>
                <order>02</order>
            </Items>
            <Items name="op_object2">
                <something1>something2</something1>
                <value>someValue2</value>
                <order>03</order>
            </Items>
        </body>
    </Ratings>
</rss>

You really don't want to do this using low-level DOM interfaces. Here's how to do it in XSLT 3.0 (which you can call from Java after installing Saxon-HE):

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform> version="3.0">
    <xsl:mode on-no-match="shallow-copy"/>
    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="*[*/order]">
        <xsl:copy>
            <xsl:apply-templates>
                <xsl:sort select="number(order)"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:transform>

With a few extra lines of code you could also do it using XSLT 1.0, which comes bundled with the JDK.

How it works:

  • The xsl:mode declaration says that the default action for elements is to copy the element and then process its children

  • xsl:strip-space says ignore whitespace in the input

  • xsl:output says add indentation in the output

  • The xsl:template rule says that when processing an element that has order elements among its grandchildren, copy the start and end tag, and process the children in sorted order of the numeric value of their order child element.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM