在XSLT属性中将ISO-8859-1字符视为UTF-8

时间:2012-01-22 17:39:55

标签: utf-8 iso-8859-1 xalan xslt

如果我确保始终将ISO-8859-1用作编码,则¬字符(ISO-8859-1中的0xAC)适用于普通文本。但是,在属性中使用它时,它会转义为:%C2%AC。我知道它需要为url转义,但不是为什么它以与UTF-8相同的方式逃脱它,而不仅仅是%AC,因为我期望它为ISO-8859-1

由于转义是在输出html文件中,唯一的结论是xslt处理器是原因。

示例:

对我而言:

使用xsltproc生成输出,针对libxml 20707,libxslt 10126和libexslt 815编译。这是#! Linux(amd64)。我也尝试过:xmlstarlet tr(也使用libxml),xalan和谷歌浏览器(通过添加<?xml-stylesheet ... >,请参阅input_ss.xml标记),结果相同。

Opera根本不会逃避它,它允许¬在字面上使用url和属性。

这是xslt的标准行为还是属性转义方式的错误?无论哪种方式,除了将%C2%AC替换为%AC之外,是否有其他解决方案,请注意,对于有效ISO-8859-1且UTF-8无效的其他字符几乎肯定是相同的。< / p>

2 个答案:

答案 0 :(得分:3)

这里使用了3种不同的基于文本的技术,XML,HTML和URI。

所有这些都具有转义机制 - 也就是说,使用文本指示其他文本在给定上下文中不可能或难以指示的方式。

非符号字符¬(U + 00AC)可以在前两个转义为&#xAC;或者&#172;或者带有一些前导零,在XML和HTML中都可以(&not;也可以在HTML中工作)。无论XML或HTML的编码是什么,都会使用此转义,因为它与字符¬相关,而不是与给定字符编码中的八位字节集相关 - 实际上,我们通常只在在使用的编码中没有这样一组八位字节的情况。

在这种情况下,这是不必要的,因为输出是字符编码,其中不需要对其进行转义,因此在源代码中,您可以看到The ¬ character未转义。

此HTML包含URI的文本。 HTML的编码与此无关,因为编码是我们将HTML的文本从一台机器获取到另一台机器的方式,但是当解析HTML以读取此URI时,我们已经过了那一点并正在处理在文本层面有一些文本 - 也就是说,它不再有编码。

现在,URI有自己的转义机制。这必须在¬的情况下使用,因为它不是URI中允许的字符(与IRI相对)。遗憾的是,与XML和HTML中的转义不同,这些转义基于给定编码中的八位字节而不是字符本身的代码点。

现在很容易将此视为一个错误,但是在1994年指定了URI,并且正式化的工作可以追溯到1989/1990,而Unicode 1.0在1991年发布,并且在1996年之前没有突破性的2.0,所以后见之明比URI的发明者有更多的好处。 (HTML在很多年前就遇到了同样的问题,但是它的编码格式使得在没有很多向后兼容性问题的情况下更容易解决这个问题。)

那么,我们应该为那些八位字节使用什么编码?原始规格留下了这个未定义,但真正唯一可能的选择是UTF-8。它是唯一一种编码,它将那些常用于特殊字符的转义符用于URI,它们的转义范围为0x20 - 0x7F,同时也覆盖了所有的UCS。

也没有办法表明另一种选择可能更合适。请记住,我们正在处理文本级别,因此您对ISO-8859-1的使用完全无关紧要。即使我们在解析HTML时跟踪编码,URI也会以与文档无关的方式使用,因此我们仍然无法使用它。总而言之,如果我们必须使用基于八位字节的编码,并且我们必须保持ASCII范围内的字符与ASCII中的八位字节匹配,则编码的唯一可能基础是UTF-8。

因此,¬任意 URI中的转义必须始终为%C2%AC

可能有一些遗留系统希望URI使用其他编码,但解决方案是修复损坏的位,而不是有效的位,因此如果某些内容需要¬%AC然后通过将%C2%AC转换为接近使用它来接近它(如果它输出%AC本身,那么你当然需要在它到达外界之前将它修复到%C2%AC )。

答案 1 :(得分:2)

XSLT规范说,在序列化URI值属性时,所有非ASCII字符都使用代表该字符的UTF-8八位字节的%HH转义进行转义。尽管过去曾使用其他编码的%HH逃逸,但现在已不再使用。这完全独立于文档本身的编码。