XSL:具有多种可能格式的十进制格式

时间:2009-02-23 12:42:07

标签: xml xslt

我对XSL有一个有趣的问题。我们有一个XML输入文件,其中包含几个设置,它们定义了我们输出内容的方式。目前,我正在努力解决XSL文件中数字的格式化问题。

以下格式是可能的:

  • 1,234.5
  • 1.234,5
  • 1234,5
  • 1234.5

我在XML文件中获得了上述格式:

<?xml version="1.0" encoding="UTF-8"?>
<document>
    <settings>
        <DefaultCurrency>EUR</DefaultCurrency>
        <DefaultDateFormat>DD.MM.YYYY</DefaultDateFormat>
    <DefaultNumberFormat>1.250,65</DefaultNumberFormat>
    <AllowOrdering>true</AllowOrdering>
</settings>
<productlist>
    <item>
        <product>
            <productid>Product1</productid>
            <weight>0.123</weight>
        </product>
        <customerprice>123.03</customerprice>
    </item>
    <item>
        <product>
            <productid>Product2</productid>
            <weight>12312.123</weight>
        </product>
        <customerprice>12.00</customerprice>
    </item>
    <item>
        <product>
            <productid>Product3</productid>
            <weight>12.123</weight>
        </product>
        <customerprice>13.23</customerprice>
    </item>
</productlist>
</document>

我试图使用以下XSL文件,但我无法让它给我正确的结果(当XML中的DefaultNumberFormat被更改时,格式也必须更改)。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:decimal-format name="numberformat1" decimal-separator="." grouping-separator=","/>
    <xsl:decimal-format name="numberformat2" decimal-separator=","/>
    <xsl:decimal-format name="numberformat3" decimal-separator="," grouping-separator="."/>
    <xsl:decimal-format name="numberformat4" decimal-separator="."/>
    <xsl:template match="productlist">
        <xsl:apply-templates select="item"/>
    </xsl:template>
    <xsl:template match="item">
ItemID: <xsl:value-of select="product/productid"/>
Weigh: 
<xsl:choose>
            <xsl:when test="/document/settings/DefaultNumberFormat = '1,250.65'">
                <xsl:value-of select="format-number(product/weight, '#,##0.000', 'numberformat1')"/>
            </xsl:when>
            <xsl:when test="/document/settings/DefaultNumberFormat = '1250,65'">
                <xsl:value-of select="format-number(product/weight, '#,##0.000', 'numberformat2')"/>
            </xsl:when>
            <xsl:when test="/document/settings/DefaultNumberFormat = '1.250,65'">
                <xsl:value-of select="format-number(product/weight, '#,##0.000', 'numberformat3')"/>
            </xsl:when>
            <xsl:when test="/document/settings/DefaultNumberFormat = '1250.65'">
                <xsl:value-of select="format-number(product/weight, '#,##0.000', 'numberformat4')"/>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="settings/*"/>
</xsl:stylesheet>

我希望有人可以在这里帮助我,我想我在如何结合格式编号和数字格式方面有点麻烦...

谢谢,Martijn

2 个答案:

答案 0 :(得分:3)

在XSLT中,format-number是一个普通的XPath函数,它将字符串作为第二个和第三个参数。这些字符串不需要在样式表中指定为常量 - 它们也可以在源文档的运行时计算。

在最简单的情况下,让我们假设源文档实际上直接将参数指定为settings/picture和`settings / formatname'。如果是这样,你可以写:

<xsl:value-of select="format-number(product/weight,
                                    settings/picture,
                                    settings/formatname)"/>

或者,如果文档使用不同的表示法,需要进行转换步骤,则可以重构样式表以使用这样的XSLT变量:

<xsl:variable name="picture">
  <!-- compute the picture string here, e.g. using <xsl:choose> and -->
  <!-- /document/settings/DefaultNumberFormat -->
</xsl:variable>

<xsl:variable name="formatname">
  <!-- compute the number format name here, e.g. using <xsl:choose> and -->
  <!-- /document/settings/DefaultNumberFormat -->
</xsl:variable>

<xsl:value-of select="format-number(product/weight, $picture, $formatname)"/>

答案 1 :(得分:0)

以下转换计算要使用的数字格式

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="vDoc" select="/"/>

    <xsl:variable name="vDFormats">
        <dFormat spec="1,250.65" name="numberformat1"/>
        <dFormat spec="1250,65" name="numberformat2"/>
        <dFormat spec="1.250,65" name="numberformat3"/>
        <dFormat spec="1250.65" name="numberformat4"/>
    </xsl:variable>

    <xsl:variable name="vDefFormats" select=
     "document('')/*/xsl:variable
                      [@name='vDFormats']"/>

    <xsl:variable name="vtheFormatName" select=
     "string($vDefFormats/*
              [@spec = $vDoc/*/settings/DefaultNumberFormat]
                                   /@name
           )
   "/>

    <xsl:decimal-format name="numberformat1" 
         decimal-separator="." grouping-separator=","/>
    <xsl:decimal-format name="numberformat2" 
         decimal-separator=","/>
    <xsl:decimal-format name="numberformat3" 
         decimal-separator="," grouping-separator="."/>
    <xsl:decimal-format name="numberformat4" 
         decimal-separator="."/>

    <xsl:template match="productlist">
        <xsl:apply-templates select="item"/>
    </xsl:template>

    <xsl:template match="item">ItemID: <xsl:text/> 
        <xsl:value-of select="product/productid"/> Weigh: <xsl:text/> 
        <xsl:value-of select=
        "format-number(product/weight, 
                       '#,##0.000', 
                       $vtheFormatName)"/>
    </xsl:template>

    <xsl:template match="settings/*"/>
</xsl:stylesheet>

应用于以下XML文档

<document>
  <settings>
    <DefaultNumberFormat>1,250.65</DefaultNumberFormat>
  </settings>

    <productlist>
      <item>
        <product>
          <productid>30</productid>
          <weight>2530.45</weight>
        </product>
      </item>
    </productlist>
</document>

生成了想要的结果

ItemID: 30 Weigh: 2,530.450