【发布时间】:2014-12-31 04:57:10
【问题描述】:
我有一个这样的 XML
<?xml version="1.0" encoding="UTF-8"?>
<Report>
<table1>
<Detail_Collection>
<Detail>
<ReceiptNo>RN12345678</ReceiptNo>
<ReceiptDate>1980/11/11</ReceiptDate>
<LastName>Dela Cruz</LastName>
<FirstName>Juan</FirstName>
<PurchaseDetails>
<Item>Wood</Item>
<Price>25.65</Price>
<Quantity>2</Quantity>
</PurchaseDetails>
<PurchaseDetails>
<Item>Axe</Item>
<Price>50.56</Price>
<Quantity>5</Quantity>
</PurchaseDetails>
</Detail>
</Detail_Collection>
</table1>
</Report>
我需要使用 XSLT 1.0 将其转换为纯文本文件
我找到了这个不错的解决方案
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="text" indent="no"/>
<xsl:variable name="some_spaces" select="' '" />
<xsl:template match="/">
<xsl:apply-templates select="//Detail_Collection/Detail" />
</xsl:template>
<xsl:template match="Detail_Collection/Detail">
<xsl:apply-templates mode="format" select="SSN">
<xsl:with-param name="width" select="number(9-1)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format_date" select="DOB">
<xsl:with-param name="width" select="number(17-10)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format" select="LastName">
<xsl:with-param name="width" select="number(33-18)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format" select="FirstName">
<xsl:with-param name="width" select="number(46-34)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format_date" select="Date">
<xsl:with-param name="width" select="number(54-47)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format" select="Time">
<xsl:with-param name="width" select="number(62-55)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format" select="CurrentStreetAddress1">
<xsl:with-param name="width" select="number(90-63)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format" select="CurrentCity">
<xsl:with-param name="width" select="number(115-91)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format" select="CurrentState">
<xsl:with-param name="width" select="number(131-116)"/>
</xsl:apply-templates>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="node()" mode ="format">
<xsl:param name="width" />
<xsl:value-of select="substring(concat(text(),$some_spaces ), 1, $width+1)"/>
</xsl:template>
<xsl:template match="node()" mode="format_date">
<xsl:param name="width" />
<xsl:value-of select="substring(concat(translate(text(),'/',''),$some_spaces ), 1, $width+1)"/>
</xsl:template>
</xsl:stylesheet>
但问题是我必须根据数据类型对每个细节进行格式化,如下所示
字母数字 - 应该是 30 个字符,右侧填充空格
数字(无符号) - 应保留 15 个字符并用零填充 例如000000000012345
数字(有符号) - 应保留 15 个字符并填充零和 如果负数应表示“N”,例如N00000000012345
我的 XML 文件的输出应该是:
RN12345678 19801111Dela Cruz Juan Wood 000000000002565000000000000002
RN12345678 19801111Dela Cruz Juan Axe 000000000005056000000000000005
例如价格是负数
RN12345678 19801111Dela Cruz Juan Wood N00000000002565000000000000002
RN12345678 19801111Dela Cruz Juan Axe N00000000005056000000000000005
顺便说一句,我有一些字段有 300 个字符(如填充符),所以我不知道是否需要在变量 some_spaces 中放置 300 多个空格
日期应为 8 个字符 YYYYMMDD。
我有一个我正在使用的模板,但不确定如何将“N”用于负数以及如何根据要求格式化日期。
这是模板:
<xsl:template name="prepend-pad">
<!-- recursive template to right justify and prepend the value with whatever padChar is passed in -->
<xsl:param name="padChar" />
<xsl:param name="padVar" />
<xsl:param name="length" />
<xsl:choose>
<xsl:when test="string-length($padVar) < $length">
<xsl:call-template name="prepend-pad">
<xsl:with-param name="padChar" select="$padChar"/>
<xsl:with-param name="padVar" select="concat($padChar,$padVar)"/>
<xsl:with-param name="length" select="$length"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring($padVar,string-length($padVar) - $length + 1)" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
谢谢
【问题讨论】:
-
XSL 版本在这里可能很重要,例如访问castable as
-
你能发布你的例子的预期结果吗? XSLT 与您的 XML 不匹配,因此不清楚您要输出哪些详细信息。 -- 另外,您没有为日期指定格式。
-
嗨,Michael,编辑了我的帖子以包含预期的结果,谢谢