通过字母数字格式从多个节点排序

时间:2013-08-07 13:54:53

标签: xslt-1.0 xslt-2.0

        <?xml version="1.0" encoding="UTF-8"?>
<accountList>
    <previousAccount>
        <account>
            <lastName>NASH</lastName>
            <accountStatus>REMOVED</accountStatus>
            <accNo>8D</accNo>
        </account>
        <account>
            <lastName>ADOGA</lastName>
            <accountStatus>REMOVED</accountStatus>
            <accNo>8A</accNo>
        </account>
        <account>
            <lastName>LUCAS</lastName>
            <accountStatus>HOLD</accountStatus>
            <accNo>9A</accNo>
        </account>
        <account>
            <lastName>DONALD</lastName>
            <accountStatus>HOLD</accountStatus>
            <accNo>10D</accNo>
        </account>
        <account>
            <accountStatus>HOLD</accountStatus>
            <lastName>LONDON</lastName>
            <accNo>10B</accNo>
        </account>
    </previousAccount>
    <account>
        <Title>Mr</Title>
        <firstName>RICHARD</firstName>
        <lastName>JOHN</lastName>
        <city>london</city>
        <accNo>5A</accNo>
    </account>
    <account>
        <Title>Mr</Title>
        <firstName>xxx</firstName>
        <lastName>JOHN</lastName>
        <city>London</city>
        <accNo>5D</accNo>
    </account>
    <account>
        <Title>Mr</Title>
        <firstName>HEWIT</firstName>
        <lastName>JOHN</lastName>
        <city>LONDON</city>
        <accNo>20B</accNo>
    </account>
    <account>
        <Title>Mr</Title>
        <firstName>xxx</firstName>
        <lastName>JOHN</lastName>
        <city>LONDON</city>
        <accNo>21D</accNo>
    </account>
    <account>
        <Title>Mr</Title>
        <firstName>KEVIN</firstName>
        <lastName>PETE</lastName>
        <city>LONDON</city>
        <accNo>5F</accNo>
    </account>
</accountList>

xslt代码

<xsl:stylesheet version="2.0"
    xsi:schemaLocation="http://www.w3.org/1999/XSL/Transform file:/C:/Users/n434947/Desktop/workspace/SonicXSLT/BA xslt page.xsd"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="text"/>
<xsl:variable name="newline">
    <xsl:text>
    </xsl:text>
</xsl:variable>
<xsl:template match="accountList">
    <xsl:for-each-group select="descendant::account" group-starting-with="*[firstName != 'xxx' or lastName != preceding-sibling::*[1]/lastName]">
        <xsl:sort select="accNo" data-type="number"/>
        <xsl:value-of select="accNo"/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="accountStatus"/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="lastName"/>
        <xsl:value-of select="$newline"/>
    </xsl:for-each-group>
</xsl:template>

在我的要求中,我得对不同节点的accNo进行排序。我想我会用代码而不是单词更好地解释这个,     为accountList / previousAccount /帐号/ ACCNO     为accountList /帐户/ ACCNO

我使用了后代,这对我的要求不起作用。我已经使用了两个for-each用于两个节点并且分开进行了排序。最后但并非最不重要的是我需要按字母数字组合排序。

实际输出

    8D REMOVED NASH
    8A REMOVED ADOGA
    9A HOLD LUCAS
    10D HOLD DONALD
    10B HOLD LONDON
    5A  JOHN
    20B  JOHN
    5F  PETE

期待输出

    5A  JOHN
    5F  PETE
    8A REMOVED ADOGA
    8D REMOVED NASH
    9A HOLD LUCAS
    10B HOLD LONDON
    10D HOLD DONALD
    20B  JOHNaccNo will be in sorted manner.

主要问题是无法按照字母数字组合排序,如2A,2B,3B,3G

1 个答案:

答案 0 :(得分:0)

这是一个肮脏的解决方案......使用此功能:

<xsl:function name="px:toInteger" as="xs:double">
    <xsl:param name="value" as="xs:string"/>
    <xsl:variable name="letter" select="replace($value, '\d', '')"/>
    <xsl:variable name="digit" select="xs:integer(replace($value, '\D', ''))" as="xs:integer"/>
    <xsl:variable name="codepoints" select="xs:integer(string-to-codepoints($letter))" as="xs:integer"/>
    <xsl:value-of select="$digit + ($codepoints div 100000)"/>
</xsl:function>

并在xsl:sort:

中调用它
<xsl:sort select="px:toInteger(accNo)" data-type="number"/>

它适用于整数+一个字符,就像您的样本一样。