XSLT 2.0 - 排序问题

时间:2018-03-13 17:11:59

标签: xml sorting xslt xslt-2.0

我在下面输入XML并且在使用XSLT排序数字时遇到问题。我尝试了多种逻辑,但无法生成预期结果。我只能在只有一个AccountNo时对数据进行排序,但是当记录有多个AccountNo并且抛出太多对键值进行排序的错误时,我会遇到问题。我想通过AccountNo对数据进行排序。

<-------XML Data---------->

<?XML version="1.0" encoding="UTF-8">
<Bank>
    <Customer>
        <Account>
            <AccountNo>999</AccountNo>
            <AccountNo>1004</AccountNo>
            <AccountNo>1002</AccountNo>
        </Account>
        <FirstName>Ramesh</FirstName>
        <LastName>Patel</LastName>
        <ContactNo>1234567890</ContactNo>
    </Customer>
    <Customer>
        <Account>
            <AccountNo>1001</AccountNo>
        </Account>
        <FirstName>Viraj</FirstName>
        <LastName>Shah</LastName>
        <ContactNo>4567890989</ContactNo>
    </Customer>
    <Customer>
        <Account>
            <AccountNo>1003</AccountNo>
            <AccountNo>1005</AccountNo>
        </Account>
        <FirstName>Kapil</FirstName>
        <LastName>Sharma</LastName>
        <ContactNo>3456789320</ContactNo>
    </Customer>
</Bank>

    <---------Expected output------->
    999     Ramesh  Patel  1234567890
    1001    Viraj   Shah   4567890989
    1002    Ramesh  Patel  1234567890
    1003    Kapil   Sharma 3456789320
    1004    Ramesh  Patel  1234567890
    1005    Kapil   Sharma 3456789320

1 个答案:

答案 0 :(得分:2)

我要做的是将模板应用于所有AccountNo元素并对它们进行排序。

然后匹配AccountNo并输出条目...

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/*">
    <xsl:apply-templates select=".//AccountNo">
      <xsl:sort data-type="number"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="AccountNo">
    <xsl:value-of select="string-join((.,../../(FirstName,LastName,ContactNo)),'&#x9;')"/>
    <xsl:text>&#xA;</xsl:text>
  </xsl:template>

</xsl:stylesheet>

<强>输出

1000    Ramesh  Patel   1234567890
1001    Viraj   Shah    4567890989
1002    Ramesh  Patel   1234567890
1003    Kapil   Sharma  3456789320
1004    Ramesh  Patel   1234567890
1005    Kapil   Sharma  3456789320

工作小提琴:http://xsltfiddle.liberty-development.net/948Fn5o

<强>更新

由于您的输出应该在固定字段中,我建议您创建一个函数,您可以使用该函数填充带有空格的字符串以适合字段。这将允许您保证该字段正好是您想要的宽度。

示例...

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:l="local">
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/*">
    <xsl:apply-templates select=".//AccountNo">
      <xsl:sort data-type="number"/>
    </xsl:apply-templates>
  </xsl:template>

  <!--Note: If the string to pad is longer than the width specified, the string
  will be truncated to fit the width.-->
  <xsl:function name="l:pad">
    <xsl:param name="toPad" as="xs:string?"/>
    <xsl:param name="width" as="xs:integer"/>
    <xsl:variable name="padding" 
      select="for $x in 1 to $width - string-length(normalize-space($toPad)) return ' '"/>
    <xsl:value-of 
      select="substring(
      concat(normalize-space($toPad), string-join($padding,'')),
      1,$width)"/>
  </xsl:function>  

  <xsl:template match="AccountNo">
    <xsl:value-of select="(
      l:pad(.,8),
      ../../(
      l:pad(FirstName,8),
      l:pad(LastName,8),
      l:pad(ContactNo,10)
      ),'&#xA;')"/>
  </xsl:template>

</xsl:stylesheet>

更新了小提琴:http://xsltfiddle.liberty-development.net/948Fn5o/3