[xsl] Re: Return structured java Object (e.g. List) to XSLT for further processing

Subject: [xsl] Re: Return structured java Object (e.g. List) to XSLT for further processing
From: "Houghton,Andrew houghtoa@xxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 15 Dec 2014 23:47:54 -0000
You can sort this with just XSLT 2.0. I suspect you need a custom sort
function to get items in the order you expect. My assumption is that when @nr
is a number then its sorted numerically and when @nr is alphabetic its
sorted alphabetically. Further assumption is that numeric footnote marks come
before alphabetic footnote marks. Your XSLT 2.0 would look like:

XML instance document
<footnotes>
  <footnote nr="9">footnote #9</footnote>
  <footnote nr="5">footnote #5</footnote>
  <footnote nr="6">footnote #6</footnote>
  <footnote nr="1">footnote #1</footnote>
  <footnote nr="3">footnote #3</footnote>
  <footnote nr="2">footnote #2</footnote>
  <footnote nr="4">footnote #4</footnote>
  <footnote nr="11">footnote #11</footnote>
  <footnote nr="b">footnote #b</footnote>
  <footnote nr="xy">footnote #xy</footnote>
  <footnote nr="a">footnote #a</footnote>
  <footnote nr="x">footnote #x</footnote>
</footnotes>

XSLT 2.0 transform document
<xsl:transform version="2.0"
  exclude-result-prefixes="#all"
  xmlns=""
  xmlns:local="http://localhost/";
  xmlns:xs="http://www.w3.org/2001/XMLSchema";
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>
  <xsl:output method="text"
    media-type="text/plain" encoding="utf-8"
    byte-order-mark="no" normalization-form="NFC"
  />
  <xsl:function name="local:footnote-numeric-sort-key" as="xs:integer?">
    <xsl:param name="node" as="element()" />
    <xsl:sequence select="if (matches(normalize-space($node/@nr), '^\d+$'))
then xs:integer(normalize-space($node/@nr)) else ()" />
  </xsl:function>
  <xsl:function name="local:footnote-text-sort-key" as="xs:string">
    <xsl:param name="node" as="element()" />
    <xsl:sequence select="if (matches(normalize-space($node/@nr), '^\d+$'))
then '' else normalize-space($node/@nr)" />
  </xsl:function>
  <xsl:template match="footnote" as="item()*">
    <xsl:value-of separator="" select="(normalize-space(.), '&#10;')" />
  </xsl:template>
  <xsl:template match="/" as="item()*">
    <xsl:apply-templates select="*[1]/footnote">
      <xsl:sort order="ascending" data-type="text"
select="local:footnote-text-sort-key(.)" />
      <xsl:sort order="ascending" data-type="number"
select="local:footnote-numeric-sort-key(.)" />
    </xsl:apply-templates>
  </xsl:template>
</xsl:transform>


Hope that helps, Andrew.

Current Thread