我正在尝试将 UTF-8 xml 源文件转换为 iso-8859-1 xml 目标文件。 我希望 XSLT 删除 iso-8859-1 中无效的所有字符。有可能吗?
理想的方法是接收目标编码作为参数,删除有关此编码的所有无效字符,并使用该参数在xsl:output tag
中设置编码属性。
我对包含中文字符的文件执行了测试,我的 XSLT 包含
<xsl:output method="xml" encoding="iso-8859-1" indent="yes" />
但中文字符转换为&amp;#20320 ;
提前致谢。
答案 0 :(得分:1)
假设XSLT 1.0:
这是可能的,但相当乏味。您需要列出集合中的所有字符,然后在输出到结果树的每个文本节点上使用translate()函数(两次)。例如,这个样式表:
<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:strip-space elements="*"/>
<xsl:param name="charset" select="'1234567890'" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="translate(., translate(., $charset, ''), '')"/>
</xsl:template>
</xsl:stylesheet>
应用于以下输入时:
<input>
<para>John has 3 apples.</para>
<para>Eve has 2 oranges.</para>
</input>
将导致:
<?xml version="1.0" encoding="UTF-8"?>
<input>
<para>3</para>
<para>2</para>
</input>
答案 1 :(得分:1)
XSL输出编码确定输出文件所在的编码。
它保证写入输出文件/流的字符不在定义的字符范围之外,在本例中为iso-8859-1
。并且字符串'你'
在该范围内,即使它所代表的字符(U + 4F60,你)不是。
<output charset="...">
指令切换字节编码(例如'你'
在UTF-8中为0xE4 0xBD 0xA0
,在UTF-16中为0x60 0x4F
但如果不可能它不会破坏你的文本,也就是说它不会在输出中替换输入中的中文字符(甚至更糟,没有)。
它尝试使用定义良好的编码方案来保留字符:编号的字符实体。显示数据的用户代理可以将其显示为问号,如果具有该功能,则可以将其显示为原始字符。
以下XML:
<?xml version="1.0" encoding="iso-8859-1"?>
<test>你</test>
和
<?xml version="1.0" encoding="UTF-8"?>
<test>你</test>
都显示为
<test>你</test>
在我的浏览器中,你的XSLT处理器所做的事实上是正确的事情。想想你真的想要丢失那些角色。
答案 2 :(得分:1)
对于iso-8859-1,您可以
replace($x, '[^-ÿ]', '')
但这并不能概括为其他编码。
如果您正在使用Saxon,那么我建议您自定义序列化程序(您可以设置自己的SerializerFactory,它可以创建一个包含您自己的XMLEmitter的管道,它可以将标准XMLEmitter子类化为省略不在选中的字符编码而不是转义它们。)
或者,对输出进行后处理(例如使用Perl或Awk)以删除所有数字字符引用。
然而,不仅如此,我还会质疑这一要求。你想做什么似乎不是一件好事。