4

So you have a third-party web service that likes to abuse XML and return things in an order that makes your programming a complete pain in the neck. For example...

<file>
  <node1>Foo</node1>
  <price>4.99</price>
  <node2>
    <key>XX999</key>
  </node2>
</file>

There are about a thousand of these sorted in order by price.

How can you re-sort this XML document by the key value?

I need the result to be a sorted XML file. Thanks!

EDIT: .NET version 2.0 (no LINQ)

2
  • You should define what you mean by sorting. I see nothing wrong with the XML you posted. Commented Apr 4, 2009 at 11:53
  • Assume I have a thousand of those nodes in order by price. I need them sorted in order by key. Commented Apr 5, 2009 at 2:35

4 Answers 4

11

Here's how to do it with XSLT:

assuming your data takes this form (file.xml):

<?xml version="1.0"?>
<listing>
<file>
  <node1>Foo</node1>
  <price>4.99</price>
  <node2>
    <key>XX999</key>
  </node2>
</file>
<file>
  <node1>Bar</node1>
  <price>5.67</price>
  <node2>
    <key>aa743</key>
  </node2>
</file>
<file>
  <node1>Was</node1>
  <price>5.67</price>
  <node2>
    <key>rr321</key>
  </node2>
</file>
</listing>

This transform (stylesheet.xsl):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="listing">
    <xsl:copy>
      <xsl:apply-templates select="file">
        <xsl:sort select="node2/key" data-type="text"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

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

</xsl:stylesheet>

When used with this .Net code (need to add a using System.Xml;):

XslCompiledTransform xslt= new XslCompiledTransform();
xslt.Load(@"c:\stylesheet.xsl");

xslt.Transform(@"C:\file.xml", @"c:\sorted.xml");

Results in this output in sorted.xml:

<?xml version="1.0" encoding="utf-8"?>
<listing>
  <file>
    <node1>Bar</node1>
    <price>5.67</price>
    <node2>
      <key>aa743</key>
    </node2>
  </file>
  <file>
    <node1>Was</node1>
    <price>5.67</price>
    <node2>
      <key>rr321</key>
    </node2>
  </file>
  <file>
    <node1>Foo</node1>
    <price>4.99</price>
    <node2>
      <key>XX999</key>
    </node2>
  </file>
</listing>
Sign up to request clarification or add additional context in comments.

6 Comments

No, I need to sort this prior to parsing the XML. I'd prefer to have a way to sort it without casting it to an object.
"How are you consuming this data?" It's nothing but a classic HTTP request, and I have a huge string to be parsed.
XSLT? Please hook me up with an example or something - I am clueless!
OK I am reading W3 specs on XSLT, but what would the select string be?
Excellent answer! Reformatted your stylesheet to enhance readability.
|
3

Apply an Xml Style Sheet to transform to source XML into an XML format suitable for your use. You can easily sort elements by values during the xsl transformation.

Comments

1

XSLT rules, of course, but I'd go with LINQ To XML (i.e., what's in the System.Xml.Linq namespace). Specifically, what you need to do is something like this:

newElement = new XElement(oldElement.Elements().OrderBy(x => x.Whatever);

Comments

0

Will Linq to XML handle this for you?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.