XSLT Sorting this XML...

  • Thread starter Philipp Lenssen
  • Start date
P

Philipp Lenssen

I have this XML file which I would like to XSLT-sort based on the
string contained within the item-children elements using basic MSXML
(no recent version of IIS, so it might be an outdated MSXML -- pretty
sure not MSXML4, though tips on how to do it with that are appreciated
too):

----------- Translation Dictionary (German) ----
<?xml version="1.0" encoding="iso-8859-1"?>
<items>
<item id="4">
<Deutsch>Registrieren</Deutsch>
<Englisch-GB>Register</Englisch-GB>
<Englisch-US>Register</Englisch-US>
<Französisch>S'enregistrer</Französisch>
<Italienisch>Registra</Italienisch>
<Spanisch>Darse de alta</Spanisch>
<Portugiesisch></Portugiesisch>
<Niederländisch>Registreren</Niederländisch>
<Kommentar></Kommentar>
</item>
<item id="5">
<Deutsch>Login</Deutsch>
<Englisch-GB>Login</Englisch-GB>
<Englisch-US>Login</Englisch-US>
<Französisch>Login</Französisch>
<Italienisch>Login</Italienisch>
<Spanisch>Inicio de sesión</Spanisch>
<Portugiesisch></Portugiesisch>
<Niederländisch>Login</Niederländisch>
<Kommentar></Kommentar>
</item>
<!-- ... and many more item-elements -->
</items>
------------------------------------------------

Thanks for any tips!


(P.S.: Am always disappointed by lack of XPath sorting features. It's a
hassle compared to e.g. SQL. Last time I had to implement an object
with an object sorter to sort some integers in XML. I also tried
XSLT-sorting from examples found online but often ran into troubles, I
believe it also has to do with limited capabilities of basic-MSXML as
installed with older versions of IIS.)
 
M

Martin Honnen

Philipp said:
I have this XML file which I would like to XSLT-sort based on the
string contained within the item-children elements using basic MSXML
(no recent version of IIS, so it might be an outdated MSXML -- pretty
sure not MSXML4, though tips on how to do it with that are appreciated
too):

----------- Translation Dictionary (German) ----
<?xml version="1.0" encoding="iso-8859-1"?>
<items>
<item id="4">
<Deutsch>Registrieren</Deutsch>
<Englisch-GB>Register</Englisch-GB>
<Englisch-US>Register</Englisch-US>
<Französisch>S'enregistrer</Französisch>
<Italienisch>Registra</Italienisch>
<Spanisch>Darse de alta</Spanisch>
<Portugiesisch></Portugiesisch>
<Niederländisch>Registreren</Niederländisch>
<Kommentar></Kommentar>
</item>
<item id="5">
<Deutsch>Login</Deutsch>
<Englisch-GB>Login</Englisch-GB>
<Englisch-US>Login</Englisch-US>
<Französisch>Login</Französisch>
<Italienisch>Login</Italienisch>
<Spanisch>Inicio de sesión</Spanisch>
<Portugiesisch></Portugiesisch>
<Niederländisch>Login</Niederländisch>
<Kommentar></Kommentar>
</item>
<!-- ... and many more item-elements -->
</items>


Assuming you want to copy all nodes while ordering the children of
<item> by their content the following is an XSLT 1.0 stylesheet that
does that:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:eek:utput method="xml" indent="yes" encoding="ISO-8859-1" />

<xsl:template match="item">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="*">
<xsl:sort data-type="text" order="ascending" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>

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

</xsl:stylesheet>

The result of the example file transformed with Xalan is

<?xml version="1.0" encoding="ISO-8859-1"?>
<items>
<item id="4">
<Portugiesisch/>
<Kommentar/>
<Spanisch>Darse de alta</Spanisch>
<Englisch-GB>Register</Englisch-GB>
<Englisch-US>Register</Englisch-US>
<Italienisch>Registra</Italienisch>
<Niederländisch>Registreren</Niederländisch>
<Deutsch>Registrieren</Deutsch>
<Französisch>S'enregistrer</Französisch>
</item>
<item id="5">
<Portugiesisch/>
<Kommentar/>
<Spanisch>Inicio de sesión</Spanisch>
<Deutsch>Login</Deutsch>
<Englisch-GB>Login</Englisch-GB>
<Englisch-US>Login</Englisch-US>
<Französisch>Login</Französisch>
<Italienisch>Login</Italienisch>
<Niederländisch>Login</Niederländisch>
</item>
<!-- ... and many more item-elements -->
</items>


As for MSXML, as far as I know MSXML 3.0 is the first to support XSLT
1.0 (which is indentified by the namespace URI
http://www.w3.org/1999/XSL/Transform). Earlier versions only support
some working draft (WD) with a different namespace and different
elements and semantics. I stronly suggest to get your ISP to install at
least MSXML 3.0 if you want to do XSLT 1.0 transformations.
 
P

Philipp Lenssen

Martin said:
Philipp Lenssen wrote:


Assuming you want to copy all nodes while ordering the children of
<item> by their content the following is an XSLT 1.0 stylesheet that
does that:

I'm sorry, I should have made this clear: I want to sort by a certain
language (the children of "item"-element are language-names in German).
For example, I pass the parameter "Deutsch", and then it should sort
alphabetically by the "Deutsch"-element's text-content. Same for e.g.
"Italienisch". I will keep your current solution for another day.
Thanks for your help so far!
 
M

Mats Kindahl

Philipp Lenssen said:
Martin said:
Philipp Lenssen wrote:
[snip]

I'm sorry, I should have made this clear: I want to sort by a certain
language (the children of "item"-element are language-names in German).
For example, I pass the parameter "Deutsch", and then it should sort
alphabetically by the "Deutsch"-element's text-content. Same for e.g.
"Italienisch". I will keep your current solution for another day.
Thanks for your help so far!

I'm not familiar with MSXML (I'm using Xalan), but something like this
should work...

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:eek:utput method="xml" indent="yes" encoding="ISO-8859-1"/>

<xsl:template match="items">
<xsl:apply-templates select="item">
<xsl:sort select="item/Deutsch"/>
</xsl:apply-templates>
</xsl:template>

<!-- insert all other templates to process the items -->

</xsl:stylesheet>

Best wishes,
Mats Kindahl
--
IAR Systems in Uppsala, Sweden.

Any opinions expressed are my own and not those of my company.

Spam prevention: contact me at (e-mail address removed) or
(e-mail address removed), removing the *NO SPAM* from the address.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top