基于Number的XSL手动排序

时间:2013-12-16 22:06:38

标签: html xml sorting xslt

我正在研究XML 1.0,试图找出一种基于我指定的数字对XML数据进行排序的方法。

html目前输出的内容如下:

Dog Name    Dog Mood
Sally       Sad
Rachel      In Heaven
Susie       Crying
April       Happy
Suvvannah   Happy

我想要实现的目标是:

Dog Name    Dog Mood
Rachel      In Heaven
Suvvannah   Happy
April       Happy
Susie       Crying
Sally       Sad

没有特定的排序顺序,而是我想要指定的顺序。我希望能够在以下xml数据中基于<trace-type>进行手动排序(请注意,此数据无法更改,它是自动生成的):

<trace-conf>
    <trace-item>
        <trace-type>1</trace-type>
        <trace-level>1</trace-level>
    </trace-item>
    <trace-item>
        <trace-type>2</trace-type>
        <trace-level>4</trace-level>
    </trace-item>
    <trace-item>
        <trace-type>3</trace-type>
        <trace-level>0</trace-level>
    </trace-item>
    <trace-item>
        <trace-type>4</trace-type>
        <trace-level>3</trace-level>
    </trace-item>
    <trace-item>
        <trace-type>5</trace-type>
        <trace-level>3</trace-level>
    </trace-item>
</trace-conf>

来自<trace-type><trace-level>的数值将与此其他xml数据文件中的值匹配。 <trace-type>NUMBER</trace-type>值与<key name="Name">值匹配,<trace-level>NUMBER</trace-level>值与<key name="Mood">值匹配。

<key name="Mood">
    <items>
        <item name="0">Crying</item>
        <item name="1">Sad</item>
        <item name="2">Okay</item>
        <item name="3">Happy</item>
        <item name="4">In Heaven</item>
    </items>
</key>

<key name="Name">
    <items>
        <item name="1">Sally</item>
        <item name="2">Rachel</item>
        <item name="3">Susie</item>
        <item name="4">April</item>
        <item name="5">Suvannah</item>
    </items>
</key>

我对XSL部分的相关内容是:

<xsl:template match="'Doggy Log'">
    <h5><xsl:value-of select="'Doggy Log'"/></h5>
    <table summary="Doggy Log">
        <tr>
            <th><xsl:call-template name="getResource"><xsl:with-param name="resID" select="'Dog Name'"/></xsl:call-template></th>
            <th><xsl:call-template name="getResource"><xsl:with-param name="resID" select="'Dog Mood'"/></xsl:call-template></th>
        </tr>
        <xsl:for-each select="trace-item">
            <tr>
                <td><xsl:value-of select="$KEY[@name = 'Name']/items/item[@name = current()/trace-type]"/></td>

                <td><xsl:value-of select="$KEY[@name = 'Mood']/items/item[@name = current()/trace-level]"/></td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

我无法按照我想指定的顺序显示<trace-type>

例如,上述“试图达到”的结果应该来自<trace-type>命令:2,5,4,3,1,这将是Rachel,Suvvannah,April,Susie,Sally。相反,我得到的是xml数据中的顺序:1,2,3,4,5,这将是Sally,Rachel,Susie,April,Suvvannah。如何手动将其分类到我需要它显示的方式?

我认为它可以用这样的东西,但它没有:

<xsl:sort select="trace-type" data-type="number" order="'2' '5' '4' '1'"/>

我确信循环可用于缩短版本,而不是显示每个和单个值,即

            <tr><td><xsl:value-of select="$KEY[@name = 'Name']/items/item[@name = current()/trace-item/trace-type = 1]"/></td></tr>
            <tr><td><xsl:value-of select="$KEY[@name = 'Name']/items/item[@name = current()/trace-item/trace-type = 2]"/></td></tr>
            <tr><td><xsl:value-of select="$KEY[@name = 'Name']/items/item[@name = current()/trace-item/trace-type = 3]"/></td></tr>
            <tr><td><xsl:value-of select="$KEY[@name = 'Name']/items/item[@name = current()/trace-item/trace-type = 6]"/></td></tr>
            <tr><td><xsl:value-of select="$KEY[@name = 'Name']/items/item[@name = current()/trace-item/trace-type = 4]"/></td></tr>
            <tr><td><xsl:value-of select="$KEY[@name = 'Name']/items/item[@name = current()/trace-item/trace-type = 5]"/></td></tr>

等。由于这个问题缩短了,实际数据有40个值要匹配。

2 个答案:

答案 0 :(得分:2)

这有点粗糙,但是这种表达应该这样做......

<xsl:sort 
     select="string-length(substring-before('25431', trace-type))" 
     data-type="number" />

当然,只有当您的所有 trace_type 值都是单位数时,这才有效。如果你想要处理多个数字值,那么它就会变得更加粗糙。

<xsl:sort 
     select="string-length(substring-before('#2#5#4#3#1#', concat('#', trace-type, '#')))" 
      data-type="number" />

答案 1 :(得分:2)

这是一个简化的情况,您希望能够适应您自己的情况。给出以下XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <objects>
        <object value="5">Echo</object>
        <object value="1">Alpha</object>
        <object value="2">Bravo</object>
        <object value="3">Charlie</object>
        <object value="4">Delta</object>
    </objects>

    <sortorder>
            <value rank="1">2</value>
            <value rank="2">5</value>
            <value rank="3">4</value>
            <value rank="4">3</value>
            <value rank="5">1</value>
    </sortorder>
</root> 

应用以下样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:key name="lookup" match="sortorder/value" use="." />

<xsl:template match="/">
<html>
<table>
<xsl:for-each select="root/objects/object">
<xsl:sort select="key('lookup', @value)/@rank" data-type="number" order="ascending"/>
    <tr>
        <td><xsl:value-of select="."/></td>
    </tr>   
</xsl:for-each>
</table>
</html>
</xsl:template>    
</xsl:stylesheet>

将返回:

Bravo
Echo
Delta
Charlie
Alpha

符合以下逻辑:

Bravo   2 --> 1
Echo    5 --> 2
Delta   4 --> 3
Charlie 3 --> 4
Alpha   1 --> 5

请注意,排序顺序可能位于另一个文档中,即使在样式表本身也是如此。