Frage

Auf der Grundlage der folgenden XML, was ist der beste Weg, um eine alphanumerische Sortierung in XSL zu erreichen?

Bearbeiten . Zu klären, unter der XML ist nur ein einfaches Beispiel der realen XML viel mehr Variante Werte enthalten würden

<colors>
  <item>
    <label>Yellow 100</label>
  </item>
  <item>
    <label>Blue 12</label>
  </item>
  <item>
    <label>Orange 3</label>
  </item>
  <item>
    <label>Yellow 10</label>
  </item>
  <item>
    <label>Orange 26</label>
  </item>
  <item>
    <label>Blue 117</label>
  </item>
</colors>

z. Ich möchte ein Endergebnis in dieser Reihenfolge:

Blue 12, Blue 117, Orange 3, Orange 26, Yellow 10, Yellow 100

Das ist " effektiv ", was ich möchte.

<xsl:apply-templates select="colors/item">
  <xsl:sort select="label" data-type="text" order="ascending"/><!--1st sort-->
  <xsl:sort select="label" data-type="number" order="ascending"/><!--2nd sort-->
</xsl:apply-templates>   

<xsl:template match="item">
  <xsl:value-of select="label"/>
  <xsl:if test="position() != last()">,</xsl:if>
</xsl:template>
War es hilfreich?

Lösung

Splitting des Beschriftungstext in Text und Zahlenteil substring-before und substring-after verwendet, wird in Ihrem Beispiel tun (aber dies ist kein allgemeiner Ansatz, aber Sie erhalten die Idee):

<xsl:template match="/">
    <xsl:apply-templates select="colors/item">
      <xsl:sort select="substring-before(label, ' ')" data-type="text" order="ascending"/>
      <!--1st sort-->
      <xsl:sort select="substring-after(label, ' ')" data-type="number" order="ascending"/>
      <!--2nd sort-->
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="item">
    <xsl:value-of select="label"/>
    <xsl:if test="position() != last()">, </xsl:if>
  </xsl:template>

Dies ergibt die folgende Ausgabe:

Blue 12, Blue 117, Orange 3, Orange 26, Yellow 10, Yellow 100

Aktualisieren

Eine generische Art und Weise Ihres Sortierproblem zu lösen, würde das select Attribut des xls:sort Elements haben sein enthält eine Zeichenfolge, die nach den Sortierregeln sortierbar ist, die Sie erwarten. Z.B. in dieser Zeichenfolge alle Zahlen konnten mit führender 0'en aufgefüllt werden, so dass sie als lexicgraphically data-type="text" Sortierung in der richtigen Reihenfolge alphanumerischen Folge.

Wenn Sie die XSLT-Engine von verwenden .NET Sie eine einfache Erweiterungsfunktion in C # zu Pad-Nummern verwenden könnten mit führenden 0'en:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:myExt="urn:myExtension"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                exclude-result-prefixes="msxsl myExt">
  <xsl:output method="xml" indent="yes" />

  <msxsl:script language="C#" implements-prefix="myExt">

    <![CDATA[
        private static string PadMatch(Match match)
        {
            // pad numbers with zeros to a maximum length of the largest int value 
            int maxLength = int.MaxValue.ToString().Length;
            return match.Value.PadLeft(maxLength, '0');
        }

        public string padNumbers(string text)
        {
            return System.Text.RegularExpressions.Regex.Replace(text, "[0-9]+", new System.Text.RegularExpressions.MatchEvaluator(PadMatch));
        }
    ]]>

  </msxsl:script>
  <xsl:template match="/">
    <sorted>
      <xsl:apply-templates select="colors/item">
        <xsl:sort select="myExt:padNumbers(label)" data-type="text" order="ascending"/>
      </xsl:apply-templates>
    </sorted>
  </xsl:template>

  <xsl:template match="item">
    <xsl:value-of select="label"/>
    <xsl:if test="position() != last()">, </xsl:if>
  </xsl:template>

</xsl:stylesheet>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top