XSLT编程:将数字转换为文字

在现代编程实践中,XSLT(可扩展样式表语言转换)是一种强大的技术,用于将XML文档转换成其他格式,如HTML、文本等。本文将介绍一个使用XSLT将数字转换为文字的程序示例。这个程序展示了XSLT的强大功能,包括使用多个命名空间、自引用函数、嵌入XML数据以及可重用模板编程等。需要注意的是,这个程序目前尚未优化,仅供实验使用,不适用于商业应用。

XSLT程序的主要特点

这个程序的主要特点包括:

  • 使用多个命名空间
  • 通过XSLT函数document()进行自引用
  • 嵌入XML数据,类似于传统编程语言中的静态数组
  • 可重用模板编程

源代码解析

以下是程序的源代码,其中包含了一些关键的XSLT标签和函数。为了便于阅读,一些字符串字面量被分成了两行。

<?xml version="1.0"?> <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:NTW="Number2Word.uri" version="1.0" exclude-result-prefixes="NTW"> <xsl:output method="text"/> <xsl:variable name="ThisDocument" select="document('')/"> <xsl:template name="NumToWord" match="/"> <xsl:param name="Number" select="'234567890.55'"/> <xsl:variable name="RoundedNumber" select="format-number($Number,'#.00')"/> <xsl:variable name="NumWhole" select="substring-before($RoundedNumber,'.')"/> <xsl:variable name="DecimalNum" select="substring-after($RoundedNumber,'.')"/> <xsl:variable name="Base10Num" select="string-length($NumWhole)"/> <xsl:for-each select="$ThisDocument//NTW:Base10[@BaseLen = $Base10Num]"> <xsl:if test="string-length(substring($NumWhole,$Base10Num - 12 + 1,3)) > 0"> <xsl:call-template name="GetWordText"> <xsl:with-param name="BasePart" select="substring($NumWhole,$Base10Num - 12 + 1,3)"/> <xsl:with-param name="BaseNumb" select="$Base10Num"/> <xsl:with-param name="BasePos" select="@BasePos1"/> </xsl:call-template> </xsl:if> <xsl:if test="string-length(substring($NumWhole,$Base10Num - 9 + 1,3)) > 0"> <xsl:call-template name="GetWordText"> <xsl:with-param name="BasePart" select="substring($NumWhole,$Base10Num - 9 + 1,3)"/> <xsl:with-param name="BaseNumb" select="$Base10Num"/> <xsl:with-param name="BasePos" select="@BasePos2"/> </xsl:call-template> </xsl:if> <xsl:if test="string-length(substring($NumWhole,$Base10Num - 6 + 1,3)) > 0"> <xsl:call-template name="GetWordText"> <xsl:with-param name="BasePart" select="substring($NumWhole,$Base10Num - 6 + 1,3)"/> <xsl:with-param name="BaseNumb" select="$Base10Num"/> <xsl:with-param name="BasePos" select="@BasePos3"/> </xsl:call-template> </xsl:if> <xsl:if test="string-length(substring($NumWhole,$Base10Num - 3 + 1,3)) > 2"> <xsl:call-template name="GetWordText"> <xsl:with-param name="BasePart" select="substring($NumWhole,$Base10Num - 3 + 1,3)"/> <xsl:with-param name="BaseNumb" select="3"/> </xsl:call-template> </xsl:if> <xsl:if test="2 >= string-length(substring($NumWhole,$Base10Num - 3 + 1,3))"> <xsl:call-template name="GetWordText"> <xsl:with-param name="BasePart" select="substring($NumWhole,$Base10Num - 3 + 1,3)"/> <xsl:with-param name="BaseNumb" select="$Base10Num"/> </xsl:call-template> </xsl:if> </xsl:for-each> <xsl:if test="number($DecimalNum) >= 20 or number($DecimalNum) = 10"> <xsl:value-of select="'and '"/> <xsl:value-of select="$ThisDocument//NTW:Tens[@Num = substring($DecimalNum,1,1) * 10]/@Word"/> <xsl:value-of select="$ThisDocument//NTW:Ones[@Num = substring($DecimalNum,2,2)]/@Word"/> </xsl:if> <xsl:if test="number($DecimalNum) > 10 and 20 > number($DecimalNum)"> <xsl:value-of select="'and '"/> <xsl:value-of select="$ThisDocument//NTW:Teens[@Num = $DecimalNum]/@Word"/> </xsl:if> <xsl:if test="10 > number($DecimalNum) and number($DecimalNum) > 0"> <xsl:value-of select="'and '"/> <xsl:value-of select="$ThisDocument//NTW:Ones[@Num = number($DecimalNum)]/@Word"/> </xsl:if> </xsl:template> <xsl:template name="GetWordText"> <xsl:param name="BasePart" select="''"/> <xsl:param name="BaseNumb" select="''"/> <xsl:param name="BasePos" select="''"/> <xsl:for-each select="$ThisDocument//NTW:Base10[@BaseLen = string-length($BasePart)]"> <xsl:if test="@BasePos4 = 1 and substring($BasePart,1,1) > 0"> <xsl:value-of select="$ThisDocument//NTW:Ones[@Num = substring($BasePart,1,1)]/@Word"/> <xsl:value-of select="$ThisDocument//NTW:BaseName[@BasePlace = string-length($BasePart) - 2]/@Name"/> </xsl:if> <xsl:if test="@BasePos4 = 1 and (substring($BasePart,2,2) >= 20 or substring($BasePart,2,2) = 10)"> <xsl:value-of select="$ThisDocument//NTW:Tens[@Num = substring($BasePart,2,1) * 10]/@Word"/> <xsl:value-of select="$ThisDocument//NTW:Ones[@Num = substring($BasePart,3,1)]/@Word"/> </xsl:if> <xsl:if test="@BasePos4 = 1 and substring($BasePart,2,2) > 10 and 20 > substring($BasePart,2,2)"> <xsl:value-of select="$ThisDocument//NTW:Teens[@Num = substring($BasePart,2,2)]/@Word"/> </xsl:if> <xsl:if test="@BasePos4 = 1 and 10 > substring($BasePart,2,2)"> <xsl:value-of select="$ThisDocument//NTW:Ones[@Num = number(substring($BasePart,3,1))]/@Word"/> </xsl:if> <xsl:if test="@BasePos4 != 1 and (substring($BasePart,1,2) >= 20 or substring($BasePart,1,2) = 10)"> <xsl:value-of select="$ThisDocument//NTW:Tens[@Num = substring($BasePart,1,1) * 10]/@Word"/> <xsl:value-of select="$ThisDocument//NTW:Ones[@Num = substring($BasePart,2,1)]/@Word"/> </xsl:if> <xsl:if test="@BasePos4 != 1 and substring($BasePart,1,2) > 10 and 20 > substring($BasePart,1,2)"> <xsl:value-of select="$ThisDocument//NTW:Teens[@Num = substring($BasePart,1,2)]/@Word"/> </xsl:if> <xsl:if test="@BasePos4 != 1 and 10 > substring($BasePart,1)"> <xsl:value-of select="$ThisDocument//NTW:Ones[@Num = substring($BasePart,1)]/@Word"/> </xsl:if> </xsl:for-each> <xsl:if test="number($BasePart) > 0"> <xsl:value-of select="$ThisDocument//NTW:BaseName[@BasePlace = $BasePos]/@Name"/> </xsl:if> </xsl:template> </xsl:transform>

如何执行这个程序

如果有msxsl.exe(可以在www.microsoft.com找到),在MS-DOS命令提示符下,输入:

msxsl NumToWord.xsl Number=100355.67

其中<XMLFILE>是任何格式良好的XML文件,Number是参数名。

如果有saxon.exe,在MS-DOS命令提示符下,输入:

saxon NumToWord.xsl Number=10055.67

其中<XMLFILE>是任何格式良好的XML文件,Number是参数名。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485