【问题标题】:XSL transformation: utf-8 and iso-8859-1 compatibilityXSL 转换:utf-8 和 iso-8859-1 兼容性
【发布时间】:2016-02-23 12:17:46
【问题描述】:

我使用 .NET 类 XslCompiledTransform 进行 xslt 转换,但我遇到了编码问题。我的输入 xml 中有这个词 Förstelärare。以下是案例:

  1. 输入xml文件有<?xml version="1.0" encoding="utf-8"?> - xslt文件有<xsl:output encoding="utf-8" ... - OK
  2. 输入xml文件有<?xml version="1.0" encoding="utf-8"?> - xslt文件有<xsl:output encoding="iso-8859-1" ... - OK
  3. 输入xml文件有<?xml version="1.0" encoding="iso-8859-1"?> - xslt文件有<xsl:output encoding="iso-8859-1" ... - OK
  4. 输入 xml 文件有 <?xml version="1.0" encoding="iso-8859-1"?> - xslt 文件有 <xsl:output encoding="utf-8" ... - 损坏 - 我在输出 xml 中看到 Förstelärare

input.xml:

<?xml version="1.0" encoding="iso-8859-1"?>
<test>Förstelärare</test>

trans.xslt:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="utf-8" standalone="yes" indent="yes"/>
    <xsl:template match="/"> 
        <xsl:apply-templates select="/test" />
    </xsl:template>
    <xsl:template match="test">
        <test><xsl:value-of select="text()"/></test>
    </xsl:template>
</xsl:stylesheet>

C#代码:

var xslCompiledTransform = new XslCompiledTransform();
using (var xmlReader = XmlReader.Create(@"C:\trans.xslt", new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore, XmlResolver = null }))
{
    xslCompiledTransform.Load(xmlReader);
}
using (var xmlReader = XmlReader.Create(@"C:\input.xml", new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore, XmlResolver = null }))
using (var xmlWriter = XmlWriter.Create(@"C:\output.xml", xslCompiledTransform.OutputSettings))
{
    xslCompiledTransform.Transform(xmlReader, xmlWriter);
}

输出.xml:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<test>Förstelärare</test>

为什么会这样?看起来我需要在我的 xslt 文件中使用 iso-8859-1 以防止损坏,因为它在 iso-8859-1utf-8 两种情况下都有效。

【问题讨论】:

  • 考虑展示最小但完整的 XML 输入、XSLT 代码和 .NET 代码示例,以便我们重现问题。
  • @MartinHonnen 添加了代码和xml。
  • 我尝试在 .NET 4.6 控制台应用程序中重现该问题,使用 VS 2012,结果文档看起来不错:&lt;?xml version="1.0" encoding="utf-8" standalone="yes"?&gt; &lt;test&gt;Förstelärare&lt;/test&gt;。当您得到乱码的非 ASCII 字符时,您确定输入文件是正确的 ISO-8859-1 编码吗?
  • 你是如何创建输入文件的?
  • 我将您显示的示例复制到 VS studio 中,并在 VS 中将编辑器窗格的编码设置为“西欧 (ISO)”并将其保存。

标签: c# xslt encoding utf-8 character-encoding


【解决方案1】:

您看到的输出是用 UTF-8 编码的字符串解释为 iso-8859-1 的结果。

有两种可能:

  • 您的源文件实际上编码为 UTF-8:仅仅因为 XML 声明说 iso-8859-1,这并不一定意味着文本就是这样保存的。 (编辑:基于 cmets,我相信这就是您的情况。)
  • 或者,当您将其写为 UTF-8 时,它工作得很好,但无论您用来检查输出,都会忽略它并假设它是 iso-8859-1。

这是它的各种编码中的字符: http://www.fileformat.info/info/unicode/char/00f6/index.htm

我建议在十六进制编辑器中查看您的源文档,然后紧跟“F”(任何编码中的 70 或 0x46),如果按照 XML 声明,如果它在 iso-8859-1 中,您应该看到 0xF6 -在这种情况下,您可能以错误的编码读取输出。如果是0xC3 0xB6,那就是UTF-8,你的源的XML声明中的编码是错误的。

【讨论】:

  • 在“0x46”之后我看到“0xc3 0xb6”。好像是utf-8。这里programmers.stackexchange.com/questions/187169/… 我看到:“例如,一个前三个字节为 0xEF,0xBB,0xBF 的文件可能是一个 UTF-8 编码文件。但是,它可能是一个 ISO-8859-1 文件,它恰好以字符"。这是我的情况。我在输入文件的开头看到 。
  • 不,这是 UTF-8 字节顺序标记:en.wikipedia.org/wiki/Byte_order_mark。绝对是 UTF-8 源文件。这意味着您的解决方法是将源中的编码更改为 UTF-8;从您的问题来看,这似乎在任何一种情况下都有效。
  • 澄清一下;虽然通常有可能(尽管极不可能)iso-8859-1 编码文件可能以这三个字符开头,但对于 XML 文档肯定不是这样,或者它不是有效的 XML。 XML 文档有效负载中的第一个字节必须是&lt; (0x3c),无论是开始注释、xml 声明、处理指令还是根元素。对于出现在它之前的这三个字节,它必须是一个字节顺序标记。
猜你喜欢
  • 2012-03-09
  • 2011-08-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-18
  • 2014-08-29
  • 2014-04-30
  • 2020-10-21
  • 2011-09-26
相关资源
最近更新 更多