كيفية تطبيق فرز أبجدي رقمي في XSLT
-
13-09-2019 - |
سؤال
بناء على XML التالية، ما هي أفضل طريقة لتحقيق فرز أبجدي رقمي في XSL؟
يحرر: لتوضيح، فإن XML أدناه هو مجرد نموذج بسيط، سيتضمن XML الحقيقي قيم أكثر تباين.
<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>
على سبيل المثال أريد نتيجة نهائية في هذا الترتيب:
Blue 12, Blue 117, Orange 3, Orange 26, Yellow 10, Yellow 100
هذا هو "على نحو فعال"ما أريد.
<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>
المحلول
تقسيم نص الملصقات إلى نص ورقم باستخدام substring-before
و substring-after
ستفعل في مثالك (ومع ذلك، هذا ليس نهجا عاما، لكن تحصل على الفكرة):
<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>
هذا يعطي الناتج التالي:
Blue 12, Blue 117, Orange 3, Orange 26, Yellow 10, Yellow 100
تحديث
وستحصل طريقة أكثر واقعية لحل مشكلة الفرز الخاصة بك select
سمة xls:sort
يحتوي العنصر على سلسلة يمكن فرزها وفقا لقواعد الفرز التي تتوقعها. على سبيل المثال في هذه السلسلة، يمكن مبطن جميع الأرقام مع قيادة 0 بحيث تقوم بفرزها بسعادة data-type="text"
سيؤدي إلى الترتيب الأبجدي الرقمي الصحيح.
إذا كنت تستخدم محرك XSLT من .NET الخاص بك، فيمكنك استخدام وظيفة ملحق بسيطة في أرقام Pad C # مع الرائدة 0's:
<?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>