我有一些 XML,我想将其转换为 Excel 将在表中打开的 XML。
但是,我的一些源数据使用字符串
来表示 CRLF 并创建一个新行。
(仅是 LF),以在单元格内创建新行。
,并且在 Excel 中获得了所需的效果,所以我知道可以做到这一点。
我认为使用像translate 这样的函数将字符串[CRLF] 交换为[LF] 会很简单。但是,到目前为止我还没有成功。
我仅限于 XLST 1.0
使用一些从 W3 借用的简单示例 .xml:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
<comment>Text on one line</comment>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<country>USA</country>
<company>RCA</company>
<price>9.90</price>
<year>1982</year>
</cd>
<cd>
<title>Still got the blues</title>
<artist>Gary Moore</artist>
<country>UK</country>
<company>Virgin records</company>
<price>10.20</price>
<year>1990</year>
<comment>Text with a break here (crlf)</comment>
</cd>
我们可以看到在
<comment>
中使用了字符串
。<xsl:for-each select="catalog/cd">
<!-- TABLE CONTENTS -->
<Row>
<!-- Title -->
<Cell>
<Data ss:Type="String">
<xsl:value-of select="title"/>
</Data>
</Cell>
<!-- Artist -->
<Cell>
<Data ss:Type="String">
<xsl:value-of select="artist"/>
</Data>
</Cell>
...
<!-- Comment -->
<Cell>
<Data ss:Type="String">
<xsl:value-of disable-output-escaping="yes" select="translate(comment,' ',' ')"/>
</Data>
</Cell>
</Row>
</xsl:for-each>
我的 XSL 标题如下所示:
?xml version="1.0" encoding = "UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
使用 [CRLF] 符号而不是字符串
,后者可以在 Excel 中使用并显示内部带有中断的单元格。如果我编辑结果以插入文本字符串
Excel 将以所需的方式打破单元格内的文本:
我被 XSLT 1.0 困住了,我是否错过了一些简单的东西?
提前非常感谢。
编辑 操作系统是WIN,我在Notepad++中使用XML工具插件在测试时执行转换。
我只是使用一些网页来测试另一个引擎: 我可以看到字段内有一个中断,但它不是测试字符串
,我不相信 Excel 会使用它在单元格内开始新行
这(还不是?)答案,但我需要一些代码的空间。
请运行以下测试:
XML
<rows>
<row>
<name>no line breaks</name>
<text>one line only</text>
</row>
<row>
<name>line feed</name>
<text>first line second line</text>
</row>
<row>
<name>carriage return</name>
<text>first line second line</text>
</row>
<row>
<name>CRLF</name>
<text>first line second line</text>
</row>
</rows>
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text">
<xsl:copy>
<xsl:value-of select="translate(., ' ', ' ')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
您应该看到如下所示的结果:
<?xml version="1.0" encoding="UTF-8"?>
<rows>
<row>
<name>no line breaks</name>
<text>one line only</text>
</row>
<row>
<name>line feed</name>
<text>first line
second line</text>
</row>
<row>
<name>carriage return</name>
<text>first line
second line</text>
</row>
<row>
<name>CRLF</name>
<text>first line
second line</text>
</row>
</rows>
如果您能够查看结果文件的十六进制转储,您应该在中间两行的换行符处看到此序列:
65 0A 73
代表人物
e, LF, s
。最后一行应该是:
65 0A 0A 73
XML 解析器将始终规范行结尾,以便输入中的实际 CRLF 序列相当于 NL(又名 LF)字符。但如果换行符被写为实体引用,例如
,则不会发生这种情况。
(请注意,
是CR,而不是您似乎建议的CRLF。)
如果换行符以这种方式绕过规范化,XSLT 处理器会将它们视为普通字符,就像任何其他字符一样。序列化程序(将 XSLT 结果树转换回词法 XML)会将 CR 字符转换为
或其他等效字符,以确保重新解析时能够进行往返。但是 NL 角色可以在往返中幸存,因此不需要这种特殊处理。
您可以使用
translate(., ' ', ' ')
将 CR 字符转换为 LF。
在 XSLT 1.0 中将 CRLF 转换为 LF 有点困难。如果您知道只有 CRLF 序列,而没有 CR 本身,那么您可以使用
translate(., ' ', '')
。