2009-04-22 14 views
2

Basierend auf dem folgenden XML, was ist der beste Weg, um eine alphanumerische Sortierung in XSL zu erreichen?So wenden Sie eine alphanumerische Sortierung in XSLT an

Bearbeiten: Um zu verdeutlichen, ist das XML unten nur ein einfaches Beispiel, das echte XML würde viel mehr abweichende Werte enthalten.

<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> 
+0

Ich aktualisiere meine Antwort mit einem allgemeineren Ansatz für das Problem. –

Antwort

6

Splitting der Beschriftungstext in Teil Text und Nummer substring-before und substring-after verwendet, wird in Ihrem Beispiel tun (dies jedoch nicht ein allgemeiner Ansatz, aber Sie bekommen 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> 

Diese gibt die folgende Ausgabe:

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

-Update

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 Zeichenkette könnten alle Zahlen mit führenden Nullen aufgefüllt werden, so dass die alphanumerische Sortierung der Wörter data-type="text" zur korrekten alphanumerischen Reihenfolge führt.

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

<?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> 
+0

danke divo ... yeah Ich schätze, meine Beispieldaten sind etwas zu generisch ;-) In der Realität gibt es vielleicht kein Trennzeichen und/oder die Position der Ziffern könnte irgendwo sein. – scunliffe

Verwandte Themen