当前位置:  开发笔记 > Android > 正文

XSLT基于输入XML的十进制格式

如何解决《XSLT基于输入XML的十进制格式》经验,为你挑选了1个好方法。

我有一种情况,我的XSLT文件应有条件地显示价格和小数,具体取决于输入XML是否包含小数.所以,我可以接收带有两种类型值的XML文件 - XML将包含格式化为小数的所有价格,最多两个位置(我称之为"Decimal-XML")或者价格将四舍五入到最接近的整数(我称之为一个"整数XML").

我的问题是我需要在XSLT文件中尽可能少地重构,然后允许它们以与XML输入相同的格式将转换应用于XHTML.为了实现这一目标,我向我的团队实施并提出了三条指导原则:

    format-number()在计算计算值或存储在变量中时,删除所有函数调用.请number()改用.但是,某些条件适用于此规则(见下文).

    要显示该值时,请使用该format-number(, '#.##')格式.这应该确保整数或十进制值将显示为最初存在于XML中.

    对于可选标签(例如"折扣"),format-number(, '0.00')即使仅计算该值,也要使用该功能.这是必要的,因为如果标签不存在,尝试获取值将得到NaN结果.

以下是XSLT的说明性示例:

  
  
    
      
        
        
Simple number() format-number(<expression>, '0.00') format-number(<expression>, '#.##')

正如HTML评论所述,它适用于大多数情况但不是全部.

我想使用单个表达式来格式化与输入相同的所有价格,而不是在任何地方应用"when-otherwise"构造,这将另外需要传递给XSLT的布尔参数来确定显示格式.XSLT的当前状态是所有数字都被舍入而不管输入如何使用format-number(, '0').

我该如何做到这一点?


编辑:在Dimitre的评论之后,我决定创建一个示例XML(以及上面的XSLT),以便专家可以轻松地尝试.

示例XML(这个包含小数):


  
    10.99
    3.99
    2.99
    2.99
  
  
    15.50
    5.50
    3.50
    3.50
  

Tomalak.. 6

如果我理解正确,你想:

"Integer-XML"总是显示为舍入数字,没有小数位

"Decimal-XML"总是显示两位小数

不使用执行格式化的模板,而是使用XPath单线程

你得到的最接近的是这个表达式:


由于在XPath 1.0(XPath 2.0if/then/else)中没有易于使用的条件表达式,因此妥协如下:


但是,这种"失败"(切断小数)时$cost,$extraCharges以及$discount加起来的轮数.

不具吸引力的替代方案是使用贝克尔的方法(后命名为奥利弗·贝克尔的胡柏林):

concat(
  substring($s1, 1, number($condition)      * string-length($s1)),
  substring($s2, 1, number(not($condition)) * string-length($s2))
)

从技术上讲,这是一个单行.这两sub-string()部分基于互斥$condition,因此concat()只返回一个值或另一个值.

实际上(特别是对于你的情况),它将是一个无法控制的混乱,缓慢而完全隐藏意图:

concat( 
  substring(
    format-number($cost + $extraCharges - $discount, '0.00')
    , 1
    , number(
      contains($cost, '.')
    ) * string-length(format-number($cost + $extraCharges - $discount, '0.00'))
  ),
  substring(
    format-number($cost + $extraCharges - $discount, '#.##')
    , 1
    , number(
      not(contains($cost, '.')) 
    ) * string-length(format-number($cost + $extraCharges - $discount, '#.##'))
  )
)

由于您声明所有输入值都包含小数,或者没有包含小数,因此上述表达式仅检查是否$cost包含小数点.这将是正确的检查$extraCharges$discount以及,我猜.



1> Tomalak..:

如果我理解正确,你想:

"Integer-XML"总是显示为舍入数字,没有小数位

"Decimal-XML"总是显示两位小数

不使用执行格式化的模板,而是使用XPath单线程

你得到的最接近的是这个表达式:


由于在XPath 1.0(XPath 2.0if/then/else)中没有易于使用的条件表达式,因此妥协如下:


但是,这种"失败"(切断小数)时$cost,$extraCharges以及$discount加起来的轮数.

不具吸引力的替代方案是使用贝克尔的方法(后命名为奥利弗·贝克尔的胡柏林):

concat(
  substring($s1, 1, number($condition)      * string-length($s1)),
  substring($s2, 1, number(not($condition)) * string-length($s2))
)

从技术上讲,这是一个单行.这两sub-string()部分基于互斥$condition,因此concat()只返回一个值或另一个值.

实际上(特别是对于你的情况),它将是一个无法控制的混乱,缓慢而完全隐藏意图:

concat( 
  substring(
    format-number($cost + $extraCharges - $discount, '0.00')
    , 1
    , number(
      contains($cost, '.')
    ) * string-length(format-number($cost + $extraCharges - $discount, '0.00'))
  ),
  substring(
    format-number($cost + $extraCharges - $discount, '#.##')
    , 1
    , number(
      not(contains($cost, '.')) 
    ) * string-length(format-number($cost + $extraCharges - $discount, '#.##'))
  )
)

由于您声明所有输入值都包含小数,或者没有包含小数,因此上述表达式仅检查是否$cost包含小数点.这将是正确的检查$extraCharges$discount以及,我猜.

推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有