Note that there are some explanatory texts on larger screens.

plurals
  1. POxsl:sort an XML file using multiple elements
    primarykey
    data
    text
    <p>I'm trying to sort a bunch of records in an XML file. The trick is that I need to sort using different elements for different nodes. To give a simplest example, I want to do this: given an xml file </p> <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt; &lt;buddies&gt; &lt;person&gt; &lt;nick&gt;Jim&lt;/nick&gt; &lt;last&gt;Zulkin&lt;/last&gt; &lt;/person&gt; &lt;person&gt; &lt;first&gt;Joe&lt;/first&gt; &lt;last&gt;Bumpkin&lt;/last&gt; &lt;/person&gt; &lt;person&gt; &lt;nick&gt;Pumpkin&lt;/nick&gt; &lt;/person&gt; &lt;person&gt; &lt;nick&gt;Andy&lt;/nick&gt; &lt;/person&gt; &lt;/buddies&gt; </code></pre> <p>I want to convert it to</p> <pre><code>Andy Joe Bumpkin Pumpkin Jim Zulkin </code></pre> <p>That is, a person may be listed by any subset of the first name, last name and a nick. The sorting key is the last name if it's present, otherwise it's the nickname if it's present and a firstname otherwise. </p> <p>I'm having difficulties here since using of variables as xsl:sort keys is <a href="https://stackoverflow.com/questions/2328896/using-variables-in-xslsort-select">apparently not allowed</a>.</p> <p>My current best shot is to have a two-step transformation: Add a special tag to each record using this stylesheet</p> <pre><code>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt; &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt; &lt;xsl:output omit-xml-declaration="no" indent="yes"/&gt; &lt;!-- *** convert each person record into a person2 record w/ the sorting key *** --&gt; &lt;xsl:template match="/buddies"&gt; &lt;buddies&gt; &lt;xsl:for-each select="person"&gt; &lt;person2&gt; &lt;xsl:copy-of select="*"/&gt; &lt;!-- add the sort-by tag --&gt; &lt;sort-by&gt; &lt;xsl:choose&gt; &lt;xsl:when test="last"&gt; &lt;xsl:value-of select="last"/&gt; &lt;/xsl:when&gt; &lt;xsl:otherwise&gt; &lt;xsl:choose&gt; &lt;xsl:when test="nick"&gt; &lt;xsl:value-of select="nick"/&gt; &lt;/xsl:when&gt; &lt;xsl:otherwise&gt; &lt;xsl:value-of select="first"/&gt; &lt;/xsl:otherwise&gt; &lt;/xsl:choose&gt; &lt;/xsl:otherwise&gt; &lt;/xsl:choose&gt; &lt;/sort-by&gt; &lt;/person2&gt; &lt;/xsl:for-each&gt; &lt;/buddies&gt; </code></pre> <p></p> <p></p> <p>And then sort the resulting xml </p> <pre><code>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt; &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt; &lt;xsl:template match="/buddies"&gt; &lt;xsl:apply-templates&gt; &lt;xsl:sort select="sort-by"/&gt; &lt;/xsl:apply-templates&gt; &lt;/xsl:template&gt; &lt;xsl:template match="person2"&gt; &lt;xsl:value-of select="first"/&gt; &lt;xsl:value-of select="nick"/&gt; &lt;xsl:value-of select="last"/&gt;&lt;xsl:text&gt; &lt;/xsl:text&gt; &lt;/xsl:template&gt; </code></pre> <p></p> <p>While this two-step transform works, I'm wondering if there is more elegant way of doing it in just one go? </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload