如何在XSLT中实现1-100数字到英文单词的动态转换
数字转英文单词的动态XSLT实现方案
需求说明
我有一个包含20个<entry>元素的XML输入文件,需要将元素内1-100的数字转换为对应的英文单词(例如20转为"Twenty")。目前已经通过XSLT变量映射数字与单词的对应关系实现了转换,能得到正确输出(比如输入46输出"Forty six"),但希望实现更具动态性的转换方案。
现有实现示例
输入XML
<input> <entry>46</entry> </input>
现有XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8" /> <xsl:variable name="numbertoword"> <number Num="1" Word="One "/> <number Num="2" Word="Two "/> <number Num="3" Word="Three "/> <number Num="4" Word="Four "/> <number Num="5" Word="Five "/> <number Num="6" Word="Six "/> <number Num="7" Word="Seven "/> <number Num="8" Word="Eight "/> <number Num="9" Word="Nine "/> <number Num="11" Word="Eleven " /> <number Num="12" Word="Twelve " /> <number Num="13" Word="Thirteen " /> <number Num="14" Word="Fourteen " /> <number Num="15" Word="Fifteen " /> <number Num="16" Word="Sixteen " /> <number Num="17" Word="Seventeen " /> <number Num="18" Word="Eighteen " /> <number Num="19" Word="Nineteen " /> <number Num="20" Word="Twenty" /> <number Num="21" Word="Twenty one"/> <number Num="22" Word="Twenty two"/> <number Num="23" Word="Twenty three"/> <number Num="24" Word="Twenty four"/> <number Num="25" Word="Twenty five"/> <number Num="26" Word="Twenty six"/> <number Num="27" Word="Twenty seven"/> <number Num="28" Word="Twenty eight"/> <number Num="29" Word="Twenty nine"/> <number Num="30" Word="Thirty " /> <number Num="31" Word="Thirty one" /> <number Num="32" Word="Thirty two" /> <number Num="33" Word="Thirty three" /> <number Num="34" Word="Thirty four" /> <number Num="35" Word="Thirty five" /> <number Num="36" Word="Thirty six" /> <number Num="37" Word="Thirty seven" /> <number Num="38" Word="Thirty eight" /> <number Num="39" Word="Thirty nine" /> <number Num="40" Word="Forty " /> <number Num="41" Word="Forty one" /> <number Num="42" Word="Forty two" /> <number Num="43" Word="Forty three" /> <number Num="44" Word="Forty four" /> <number Num="45" Word="Forty five" /> <number Num="46" Word="Forty six" /> <number Num="47" Word="Forty seven" /> <number Num="48" Word="Forty eight" /> <number Num="49" Word="Forty nine" /> <number Num="50" Word="Fifty " /> <number Num="10" Word="Ten " /> <number Num="20" Word="Twenty " /> <number Num="60" Word="Sixty " /> <number Num="70" Word="Seventy " /> <number Num="80" Word="Eighty " /> <number Num="90" Word="Ninety " /> </xsl:variable> <xsl:template match="/input"> <xsl:for-each select="entry"> <xsl:value-of select="$numbertoword/number[@Num = current()]/@Word"/> </xsl:for-each> </xsl:template> </xsl:stylesheet>
输出结果
Forty six
动态转换方案
针对1-100的数字,可以通过拆分数字的十位和个位,结合基础词汇映射来实现动态转换,避免逐个枚举所有数字:
优化后的XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8" /> <!-- 基础词汇映射:0-9、10-19、整十数、100 --> <xsl:variable name="base-numbers"> <num value="0" word=""/> <num value="1" word="One"/> <num value="2" word="Two"/> <num value="3" word="Three"/> <num value="4" word="Four"/> <num value="5" word="Five"/> <num value="6" word="Six"/> <num value="7" word="Seven"/> <num value="8" word="Eight"/> <num value="9" word="Nine"/> <num value="10" word="Ten"/> <num value="11" word="Eleven"/> <num value="12" word="Twelve"/> <num value="13" word="Thirteen"/> <num value="14" word="Fourteen"/> <num value="15" word="Fifteen"/> <num value="16" word="Sixteen"/> <num value="17" word="Seventeen"/> <num value="18" word="Eighteen"/> <num value="19" word="Nineteen"/> <num value="20" word="Twenty"/> <num value="30" word="Thirty"/> <num value="40" word="Forty"/> <num value="50" word="Fifty"/> <num value="60" word="Sixty"/> <num value="70" word="Seventy"/> <num value="80" word="Eighty"/> <num value="90" word="Ninety"/> <num value="100" word="One Hundred"/> </xsl:variable> <!-- 数字转单词的通用模板 --> <xsl:template name="number-to-word"> <xsl:param name="num"/> <xsl:choose> <!-- 处理100 --> <xsl:when test="$num = 100"> <xsl:value-of select="$base-numbers/num[@value=100]/@word"/> </xsl:when> <!-- 处理1-19的直接匹配 --> <xsl:when test="$num < 20"> <xsl:value-of select="$base-numbers/num[@value=$num]/@word"/> </xsl:when> <!-- 处理20-99:拆分十位和个位拼接 --> <xsl:otherwise> <xsl:variable name="tens" select="floor($num div 10) * 10"/> <xsl:variable name="units" select="$num mod 10"/> <xsl:value-of select="$base-numbers/num[@value=$tens]/@word"/> <xsl:if test="$units != 0"> <xsl:text> </xsl:text> <xsl:value-of select="$base-numbers/num[@value=$units]/@word"/> </xsl:if> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- 主模板处理输入XML --> <xsl:template match="/input"> <xsl:for-each select="entry"> <xsl:call-template name="number-to-word"> <xsl:with-param name="num" select="number(.)"/> </xsl:call-template> <xsl:if test="position() != last()"> <xsl:text> </xsl:text> <!-- 多个entry时换行分隔结果 --> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet>
方案说明
- 精简词汇映射:仅定义1-19、整十数和100的基础词汇,避免冗余枚举所有数字
- 动态数字拆分:
- 1-19直接匹配基础词汇
- 20-99自动拆分为十位和个位,拼接对应词汇
- 100单独处理
- 扩展性强:无需修改映射表即可处理1-100内的任意数字,后续若需扩展更大范围只需调整模板逻辑和基础词汇
内容的提问来源于stack exchange,提问作者Imran
相关产品推荐
相关产品推荐

