xmlsortingxsltmarc

XSL sorting on substrings where a value in an atribute tells where to start the substring


I have this quite trivial XML-file with titles of books I have to sort in alphabetical order, where the sorting should be without leading definite or indefinite articles, i.e. you can't take the, a, an, der, das, die, la, le, les, de, den, det....(and so on) in account when sorting.

So, desired sorting order is: Advanced teaching methods - The cultural transmission of artefacts, skills and knowledge - A day at the airport - The dynamic middle ages - A joint promotion of mathematics, science and technology - Das Kapital - Den vetenskapliga revolutionen - XML for dummies

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="indicators.xsl"?>
<report>
<catalog>
<marc>
<marcEntry tag="245" label="Title" ind="00">XML for dummies</marcEntry>
</marc>
</catalog>
<catalog>
<marc>
<marcEntry tag="245" label="Title" ind="10">Advanced teaching methods.</marcEntry>
</marc>
</catalog>
<catalog>
<marc>
<marcEntry tag="245" label="Title" ind="04">Das Kapital</marcEntry>
</marc>
</catalog>
<catalog>
<marc>
<marcEntry tag="245" label="Title" ind="14">The cultural transmission of artefacts, skills and knowledge</marcEntry>
</marc>
</catalog>
<catalog>
<marc>
<marcEntry tag="245" label="Title" ind="12">A day at the airport</marcEntry>
</marc>
</catalog>
<catalog>
<marc>
<marcEntry tag="245" label="Title" ind="14">The dynamic middle ages</marcEntry>
</marc>
</catalog>
<catalog>
<marc>
<marcEntry tag="245" label="Title" ind="12">A joint promotion of mathematics, science and technology</marcEntry>
</marc>
</catalog>
<catalog>
<marc>
<marcEntry tag="245" label="Title" ind="04">Den vetenskapliga revolutionen</marcEntry>
</marc>
</catalog>
</report>

How many characters to jump over when sorting is indicated by the second digit in the attribute ind: If ind='00' or ind='10'

<xsl:sort select="substring(marc/marcEntry[@tag='245'],1)"/>

If ind='01' or ind='11'

<xsl:sort select="substring(marc/marcEntry[@tag='245'],2)"/>

and so on until If ind='09' or ind='19'

<xsl:sort select="substring(marc/marcEntry[@tag='245'],10)"/>

To make things even more complicated: attribute ind can appear together with other tags and labels; if so, ind is not relevant for sorting.

I have absolutely no idea on where to start


Solution

  • If there is only ever one marc/marcEntry[@tag='245'] in each catalog then it should be as simple as

    <xsl:sort select="substring(marc/marcEntry[@tag='245'],
                                substring(marc/marcEntry[@tag='245']/@ind, 2) + 1)" />
    

    substring(marc/marcEntry[@tag='245']/@ind, 2) gives you the second (and subsequent) characters in the ind value, then the + 1 converts that value to a number and adds one to it.