469,362 Members | 2,352 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,362 developers. It's quick & easy.

Sort xml and output xml

I have this xml-file. I want to sort it, and create a new xml-file. The
result should be identical to the input except that it's sorted.

<?xml version="1.0" encoding="UTF-8"?>
<levelone>
<child ID="1" sort="5"><name>Paul</name></child>
<child ID="2" sort="1"><name>Adam</name></child>
<child ID="3" sort="2"><name>Will</name></child>
<root>

I now want to apply an xslt file and have the following output:
<?xml version="1.0" encoding="UTF-8"?>
<levelone>
<child ID="2" sort="1"><name>Adam</name></child>
<child ID="3" sort="2"><name>Will</name></child>
<child ID="1" sort="5"><name>Paul</name></child>
<root>

I've been searching for hours, but all the examples I have seen creates an
HTML file.

tia
/jim
Dec 5 '06 #1
10 6935

Jim Andersen wrote:
I have this xml-file. I want to sort it, and create a
new xml-file. The result should be identical to the
input except that it's sorted.
Since you failed to mention what you're using for
processing, I assume it's some XSLT 1.0-compliant
processor.
<?xml version="1.0" encoding="UTF-8"?>
<levelone>
<child ID="1" sort="5"><name>Paul</name></child>
<child ID="2" sort="1"><name>Adam</name></child>
<child ID="3" sort="2"><name>Will</name></child>
<root>
That's not an XML file. It's not well-formed.
I've been searching for hours, but all the examples I
have seen creates an HTML file.
That's mighty strange, especially since XML is the
default output method. All the XSLT tutorials I remember
covered sorting, identity transformation and controlling
your output.

Presuming you meant something like:

<levelone>
<child ID="1" sort="5"><name>Paul</name></child>
<child ID="2" sort="1"><name>Adam</name></child>
<child ID="3" sort="2"><name>Will</name></child>
</levelone>

The following XSLT should do the trick:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="*[@sort][not(preceding-sibling::*[@sort])]">
<xsl:apply-templates select="../*[@sort]" mode="copy">
<xsl:sort select="@sort"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template
match="*[@sort][preceding-sibling::*[@sort]]"/>
<xsl:template match="node()|@*" mode="copy">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

--
Pavel Lepin

Dec 5 '06 #2
p.*****@ctncorp.com wrote:
Since you failed to mention what you're using for
processing
I'm using a .NET 2.0 XMLDataSource. I point it to my xml-file and my
xslt-file.
>, I assume it's some XSLT 1.0-compliant
processor.
><?xml version="1.0" encoding="UTF-8"?>
<levelone>
<child ID="1" sort="5"><name>Paul</name></child>
<child ID="2" sort="1"><name>Adam</name></child>
<child ID="3" sort="2"><name>Will</name></child>
<root>

That's not an XML file. It's not well-formed.
Yes. A typo in my posting. The last element "root" should have been
"levelone"

>I've been searching for hours, but all the examples I
have seen creates an HTML file.

That's mighty strange, especially since XML is the
default output method.
And now I found out why. I had (from one of the examples I found) learned
that I could also put an instruction in the XML document that said to always
use a specific XSL-file. Something along the lines of : <xsl-stylesheet
output="htm/txt">
Removing that line made the output into XML.
Presuming you meant something like:

<levelone>
<child ID="1" sort="5"><name>Paul</name></child>
<child ID="2" sort="1"><name>Adam</name></child>
<child ID="3" sort="2"><name>Will</name></child>
</levelone>
I did.
The following XSLT should do the trick:
And it did. Thx a heap. Now I can start to find out why :-)

/jim
Dec 5 '06 #3
This should be trivial. See, for example, http://www.w3.org/TR/xslt#sorting

XSLT doesn't output HTML unless you tell it to output HTML...

Dec 5 '06 #4
Joseph Kesselman wrote:
This should be trivial. See, for example,
http://www.w3.org/TR/xslt#sorting
As you can see from mr p.lepins posting the solution is far from "trivial".
XSLT doesn't output HTML unless you tell it to output HTML...
An unfortunately I (unknowingly) did :-)

/jim
Dec 6 '06 #5
Jim Andersen wrote:
As you can see from mr p.lepins posting the solution is far from "trivial".
I'm not sure I agree; that solution strikes me as overcomplicated for
the question you asked.

"Produce a new levelone document, copying the child elements in sorted
order."

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template select="/levelone">
<levelone>
<xsl:for-each select="child">
<xsl:sort select="@sort"/>
<xsl:copy-of select=".">
</xsl:apply-templates>
</levelone>
</xsl:template>

</xsl:stylesheet>

Yes, things may become more complicated when additional constraints are
applied... but this ought to do the job you asked for.
--
() ASCII Ribbon Campaign | Joe Kesselman
/\ Stamp out HTML e-mail! | System architexture and kinetic poetry
Dec 6 '06 #6

Joe Kesselman wrote:
Jim Andersen wrote:
As you can see from mr p.lepins posting the solution
is far from "trivial".
As Joe Kesselman said, it does a bit more than you asked
for. Partly because I wasn't really sure what you were
asking for, your original post being just a bit sloppy,
and partly because I tend to introduce what I perceive as
useful techniques/good practices when I post solutions to
problems on the usenet. Still, it's trivial enough even
then.

The transformation I posted copies any XML document fed to
it, sorting any siblings with sort attribute by the value
of that attribute (it breaks just a bit if there are
sibling elements without sort attribute interspersed with
elements it's trying to sort).
I'm not sure I agree; that solution strikes me as
overcomplicated for the question you asked.

"Produce a new levelone document, copying the child
elements in sorted order."

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template select="/levelone">
<levelone>
<xsl:for-each select="child">
<xsl:sort select="@sort"/>
<xsl:copy-of select=".">
</xsl:apply-templates>
</levelone>
</xsl:template>
</xsl:stylesheet>
Being my usual obnoxious self, I cannot resist the
temptation to point out that, in my opinion:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/levelone">
<xsl:copy>
<xsl:apply-templates>
<xsl:sort select="@sort"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="child">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>

is only a bit more complicated, and better from the
standpoint of teaching the Arguably Right Thing.

--
Pavel Lepin

Dec 6 '06 #7
p.*****@ctncorp.com wrote:
[example]
is only a bit more complicated, and better from the
standpoint of teaching the Arguably Right Thing.
Depends on the user's intent. Yes, we want to encourage folks to learn
to take advantage of XSLT's pattern-matching and recursion capabilities.
But sometimes processing the nodes directly really does do everything
that's needed.

If the question had been posed differently, I might have solved it
differently. Your milage will vary.

--
Joe Kesselman / Beware the fury of a patient man. -- John Dryden
Dec 6 '06 #8
Joseph Kesselman wrote:
Depends on the user's intent.
My intent was to have my immediate problem solved.
AND to learn something about xslt.
AND to get a piece of code I can re-use in other scenarios, as I will
problably need to sort stuff again.

These things, I think, is something many of us posting and answering q's
want.
So p.lepin guessed right. Even if I was sloppy when asking the q.
But this was my first post in this subject, so I do net yet know what is
important, and what isn't.

/jim
Dec 7 '06 #9
Jim Andersen wrote:
My intent was to have my immediate problem solved.
AND to learn something about xslt.
AND to get a piece of code I can re-use in other scenarios, as I will
problably need to sort stuff again.
Either solution addresses those. Mine focuses on the specifics of
sorting, and trusts that you will learn to think recursively through
other examples. The other attempts to show some other aspects of the
language as well... which may be useful, or may risk obscuring the key
point.

Personally, I still think the p.lepin's solution is overcomplicated; the
use of a separate mode with its own copy of the identity template is
something worth understanding in the long run but I consider it a
distraction here.

Both are reusable. Which one is more reusable -- or teaches you more
about reuse -- is debatable.

As I say, there's always a question of just how far to digress when
answering a question. One of the nice things about asking on a newsgroup
is that you may get multiple solutions, as here, in which case you can
pick the one that matches your own needs... or, if you don't yet know
your needs, you'll at least be exposed to the fact that multiple valid
answers exist.

Have fun.

--
() ASCII Ribbon Campaign | Joe Kesselman
/\ Stamp out HTML e-mail! | System architexture and kinetic poetry
Dec 7 '06 #10
Joe Kesselman wrote:
Personally, I still think the p.lepin's solution is overcomplicated;
I have yet to fully comprehend it :-)
Both are reusable. Which one is more reusable -- or teaches you more
about reuse -- is debatable.
I tend to go with the p.lepin solution. Your solution demands that I
hard-code the names of the nodes "levelone" and "child".
p.lepins only need the "sort"-attribute to be hardcoded.

After I understand p.lepins solution better, I hope to find out if it will
work with a more deeper nested XML lilke

<levelone>
<child ID="1"
sort="5"><names><name>Paul</name><name>Anka</name></names></child>
<child ID="2" sort="1"><name>Adam</name></child>
<child ID="3" sort="2"><name>Will</name></child>
</levelone>
One of the nice things about asking on a
newsgroup is that you may get multiple solutions, as here, in which
case you can pick the one that matches your own needs... or, if you
don't yet know your needs, you'll at least be exposed to the fact
that multiple valid answers exist.

Have fun.
Thanks. To both of you. For guiding me from wet feet, to knee-deep :-)

/jim
Dec 8 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Derek Tinney | last post: by
9 posts views Thread by Raymond Lewallen | last post: by
2 posts views Thread by BjoernJackschina | last post: by
48 posts views Thread by Alex Chudnovsky | last post: by
4 posts views Thread by Gaijinco | last post: by
reply views Thread by octavia | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.