脸上长扁平疣怎么治:xml数据编码方式

来源:百度文库 编辑:九乡新闻网 时间:2024/07/08 22:32:20

DotNet 版 (精华区)

发信人: xuelu (绝情), 信区: DotNet
标  题: XML的数据编码方式
发信站: 碧海青天 (Sun Oct 14 10:05:25 2001), 转信



xml 数据的编码方式
chris lovett 
microsoft corporation
2000 年 3 月

目录 


------------------------------------------------------------------------
--------
1、跨平台数据格式
2、xml 和字符编码
3、字符集和 msxml dom
 4、用 msxml 创建新的 xml 文档
5、结论
6、有关详细信息
 

------------------------------------------------------------------------
--------

摘要:本文介绍了字符编码的工作原理,特别是在 xml 和 msxml dom 中的工作原
理。

近来很多人问我,如何使 xml 文件在不同的平台间正确地传递数据。他们创建了
 xml 文档,键入了数据,粘上了几个标记,调整了标记的格式,甚至放入了 
 声明,作为额外增添。然后他们试着装载它,可得到的却
是意想不到的出错消息,microsoft(r) xml parser (msxml) 报告说数据有问题。
对初编 xml 者来说,这真令人沮丧。难道它竟不能正常工作吗?

当然不是。当从 msxml 收到意想不到的出错消息时,很可能是因为接收数据的平
台将其存储到了与发送数据不同的平台上,结果导致了字符编码问题。

跨平台数据格式
自从计算机软件和硬件从业人员设法将两台计算机连接到一起以来,他们就一直向
着创建跨平台技术并使不同的平台能够共享数据的领域而努力奋斗。很早以来,由
于不同类型的计算机的数量、连接方式、希望共享的数据种类的急剧增加,事态也
就变得越来越复杂。

经过几十年关于跨平台编程技术的研究,当今(而且可能在未来的很长一段时期内
)唯一的真正跨平台解决方案是通过简单的标准数据格式得到的。web 的成功正是
建立在这种格式上的。在 web 服务器和 web 浏览器之间传递的主要内容是 
http 标题和 html 页,两者都是标准的文本格式。

在以下几节中,我将讨论字符编码和标准字符集、unicode、html content-type 
标题、html content-type 元标记和字符实体。如果您熟悉上述概念,可跳过这些
内容去读 encoding xml data for the xml document object model (dom) 
programmer(针对 xml 文档对象模型 (dom) 编程人员的编码 xml 数据)的提示
和技巧。有关详细信息,请参阅 xml and character encoding(xml 和字符编码
)。

关于字符编码
标准文本格式是建立在标准字符集之上的。要记住,所有的计算机均将文本存储为
数字。然而,不同的系统也可以用不同的数字存储相同的文本。下表显示了一组字
节是如何被存储的,第一个是使用默认代码页 1252、运行 microsoft windows(r)
 的典型计算机,第二个是使用 macintosh roman 代码页的典型 apple(r) 
macintosh(r) 计算机。

byte windows macintosh 
140 ? ? 
229 ? a 
231 ? á 
232 è ? 
233 é è 


比方说,如果您的祖母从 http://www.barnesandnoble.com/(英文)订购了一本
新书,她不会想到她的 macintosh 计算机存储字符的方式,并不同于运行 www.
barnesandnoble.com(英文)的新 windows 2000 web 服务器。在往 internet 订
购单的发货栏中输入瑞典家中的地址时,她相信 internet 会正确地传递字符 ?(
在其 macintosh 上的字节值是 140),并没想到接收和处理她发送消息的计算机
会将字节值 140 转换为字母 ?。

unicode
unicode consortium(统一码协会)确信(用双字节而不是单字节表示每个字符)
定义一个通用的代码页是个好主意,该代码页适用于全世界所有的语言,从而不同
代码页之间的映射问题将不复存在。

既然如此,如果 unicode 解决了跨平台的字符编码问题,那为何它却未成为唯一
的标准呢?第一个问题是,转换到 unicode 有时意味着使所有的文件大小加倍 —
 这样做在网络世界中是不可想象的。因此有人仍乐于使用老的、单字节的字符集
,如 iso-8859-1 到 iso-8859-15、shift-jis、euc-kr 等等。

第二个问题是,仍存在许多并非基于 unicode 的系统,这就意味着在网络上,某
些组成 unicode 字符的字节值可能会给那些更旧的系统造成严重问题。因此定义
了“unicode 转换格式 (utf)”;它们运用位转换技术对 unicode 字符进行编码
,使其成为在老系统上“透明的”(或可安全通过)的字节值。

此类字符编码中最普及的是 utf-8。utf-8 采用 unicode 标准的前 127 个字符(
它们恰好是基本的拉丁文字符:a-z、a-z 和 0-9,以及几个标点字符),并直接
将其映射到单字节值。然后采用位转换技术,用字节的高位来编码 unicode 字符
的其余部分。这样做的结果是,小瑞典字符 ? (0xe5) 变成了下列双字节乱码:?
¥ (0xc3 0xa5)。所以,除非您能够在脑海里进行位转换,否则,在utf-8 中编码
的数据是无法被人读懂的。

content-type 标题
因为更旧的单字节字符集仍被使用,所以只有当指定了数据所在的实际字符集之后
,传输数据的问题才能得以解决。认识到这一点后,internet 电子邮件和 http 
协议小组定义了一种标准方法,用以在消息标题 content-type 属性中指定字符集
。该属性从注册的字符集名称列表中指定一个字符集,该字符集名称是由 
internet assigned numbers authority (iana)定义的。典型的 http 标题都可能
包含下列文本:

http/1.1 200 ok
content-length: 15327
content-type: text/html; charset:iso-8859-1;
server: microsoft-iis/5.0
content-location: http://www.microsoft.com/default.htm
date: wed, 08 dec 1999 00:55:26 gmt
last-modified: mon, 06 dec 1999 22:56:30 gmt

该标题向应用程序表明,跟在标题后面的内容位于 iso-8859-1 字符集中。

content-type 元标记
content-type 属性是可选项,在有些应用程序中,http 标题的信息被去掉了,而
只有 html 本身通过。为了补救这一点,html 标准小组定义了一种可选的元标记
方法,用于指定 html 文档本身的字符集,使 html 文档字符集是自描述的。

charset=iso-8859-1">

在这种情况下,字符集 iso-8859-1 说明在此特定的 html 页中,字节值 229 表
示 ?。现在该页对任何系统来说,都是完全清楚的,数据不会被曲解。遗憾的是,
由于此元标记是可选的,所以它给错误留下了空子。

字符实体
不是所有的系统支持所有的注册字符集。例如,我并不认为很多平台实际上可支持
称为 ebcdic 的 ibm 主机字符集。windows nt 是支持的,但许多其他系统很可能
不支持 — 这大概就是 http://www.ibm.com(英文)主页为什么生成 ascii 的原
因。

作为备选方案,html 允许通过指定确切的 unicode 字符值,对该页中的单个字符
进行编码。然后将这些字符实体进行脱离字符集的分析,即可确切地确定其 
unicode 值。它的语法是 ?amp;#229;?or ?amp;#xe5;?。

xml 和字符编码
xml 从 html 那里借鉴了这些思想,并使之更进一步,定义了一个彻底明确的算法
,以确定编码使用的字符集。在 xml 中,由 xml 声明中的可选编码属性定义字符
编码。下列算法确定默认的编码:

如果文件以 unicode 字节次序标志 [0xff 0xfe] 或 [0xfe 0xff] 开头,则认为
该文档是在 utf-16 编码中。否则,它在 utf-8 中。 

以下是所有正确和等效的 xml 文档:

字符集或编码 http 标题 xml 文档 
iso-8859-1 content-type: text/xml; charset:iso-8859-1; ?lt;
/test> 
utf-8 content-type: text/xml; ?¥ 
iso-8859-1 content-type: text/xml; encoding="iso-8859-1"?>
?lt;/test> 
utf-8(用字符实体) content-type: text/xml; ? 
utf-16(带字节次序标志的 unicode) content-type: text/xml; ff fe 3c 00 
74 00 65 00 73 00 74 00 3e 00 e5 00 ..<.t.e.s.t.>...
3c 00 2f 00 74 00 65 00 73 00 74 00 3e 00 0d 00 <./.t.e.s.t.>...
0a 00 


字符集和 msxml dom
现在,讨论过不同的字符编码方法之后,让我们来看看如何在 msxml dom 中加载
 xml 文档,以及当碰到模糊编码的字符时,可能收到的出错消息的类型。加载 
xml dom 文档的两个主要方法是 loadxml 方法和 load 方法。

loadxml 方法总是采用只在 ucs-2 或 utf-16 中编码的 unicode bstr。如果将非
有效的 unicode bstr 的内容传递给 loadxml,则加载会失败。

load 方法可将以下内容当作 variant:

value des cription 
url 如果 variant 是 bstr,则将其理解为 url。 
vt_array | vt_ui1 variant 也可以是包含原始编码字节的 safearray。 
iunknown 如果 variant 是 iunknown 接口,则 dom 文档为 istream、
ipersiststream 和 ipersiststreaminit 调用 queryinterface。 


load 方法实现以下算法,用于确定 xml 的字符编码或字符集。 

如果 content-type http 标题定义了字符集,该字符集则替代 xml 文档本身的所
有内容。因为没有 http 标题,所以这显然不适用于 safearray 和 istream 机制



如果有双字节 unicode 字节次序标志,则它假设编码是 utf-16。它既可处理大 
endian,也可处理小 endian。


如果有四字节 unicode 字节次序标志 (0xff 0xfe 0xff 0xfe),则它假设编码是
 utf-32。它既可处理大 endian,也可处理小 endian。


否则,它假设编码是 utf-8,除非它用指定其他一些字符集的编码属性(如 
iso-8859-1、windows-1252、shift-jis 等),找到 xml 声明。 
您将看到两个从 xml dom 返回的指出编码问题的出错消息。第一个通常指出文档
中的字符与 xml 文档的编码不匹配:

在文本内容中发现了一个无效字符。

parseerror 对象可告诉您这个捣乱字符在某一行的确切位置,以便使您解决该问
题。

第二个出错消息指出您一开始用的是 unicode 字节次序标志(或调用了 
loadxml 方法),然后编码属性指定了不是双字节编码的编码(如 utf-8 或 
windows-1250): 

不支持从当前编码转换到指定的编码。

另外,您可能调用了 load 方法,并在一开始使用了单字节编码(没有字节次序标
志),但是它随后发现了指定双字节或四字节编码(如 utf-16 或 ucs-4)的编码
属性。 

基本原则是不能利用 xml 声明的编码属性,在多字节字符集如 utf-8、shift-jis
 或 windows-1250,与 unicode 字符编码如 utf-16、ucs-2 或 ucs-4 之间进行
转换,这是因为声明本身必须对每个字符都使用与文档其余部分相同数量的字节。


最后,ixmlhttprequest 接口提供如下方法,用以访问下载的数据:

methods desc ription 
responsexml 表示由 msxml dom 分析器分析的响应实体(用与 load 方法相同的
规则)。 
responsetext 表示作为字串的响应实体。本方法盲目地解码从 utf-8 收到的消息
实体。这是一个已知问题,应在即将面市的 msxml web release 中得到解决。 
responsebody 表示作为无符号字节数组的响应实体。 
responsestream 表示作为 istream 接口的响应实体。 


用 msxml 创建新的 xml 文档
一旦加载了 xml 文档,即可用 dom 处理 xml 文档,而不必考虑任何编码问题,
因为文档是作为 unicode 存储在内存中的。所有 xml dom 接口都是基于 com 
bstr 的,后者是双字节的 unicode 字串。这就是说,您可以从新开始在包含所有
 unicode 字符的内存中建立 msxml dom 文档,并且所有组建将会共享该内存中的
 dom,而不会对 unicode 字符值的意思有任何疑惑。然而,当对其进行保存时,
msxml 将以默认方式按 utf-8 编码所有数据。例如,假设您进行了以下处理:

var xmldoc = new activexobject("microsoft.xmldom")
var e = xmldoc.createelement("test");
e.text = "?;
xmldoc.appendchild(e);
xmldoc.save("foo.xml");

下列 utf-8 编码文件的结果是:

?¥

注意 上述例子只有当在浏览器以外的环境运行时,才有效。由于受到安全限制,
在浏览器里调用 save 方法将不会产生相同的结果。

尽管这看上去有点怪,但却是正确的。下列测试装载了用 utf-8 编码的文件,并
测试 utf-8 是否被重新解码为 unicode 字符值 229。它是:

var xmldoc = new activexobject("microsoft.xmldom")
xmldoc.load("foo.xml");
if (xmldoc.documentelement.text.charcodeat(0) == 229)
{
    wsc ript.echo("yippee - it worked !!");
}

要想更改 xml dom save 方法使用的编码,需要用如下位于文档顶部的编码属性创
建 xml 声明:

var pi = xmldoc.createprocessinginstruction("xml", 
                        " version='1.0' encoding='iso-8859-1'");
xmldoc.appendchild(pi);

调用 save 方法时,您就会得到以下用 iso-8859-1 编码的文件:


?lt;/test>

现在,小心不要被 xml 属性迷惑。xml 属性返回 unicode 字串。如果在创建 
iso-8859-1 编码声明之后,调用 domdocument 对象上的 xml 属性,即可取回以
下 unicode 字串:


?lt;/test>

请注意这里没有 iso-8859-1 编码声明了。这是正常的。这样做的原因是使您可以
转而用此字串调用 loadxml,它会起作用。如果它不这么做,loadxml 会失败并返
回出错消息:“不支持从当前编码切换到指定的编码。”

结论
但愿本文有助于解释字符编码的工作原理,特别是在 xml 和 msxml dom 中的工作
原理。一旦您理解了字符集编码,它是相当简单的,而且 xml 是非常出色的,因
为它在这方面未留有丝毫含糊的余地。尽管 msxml dom 有几处怪异需要密切留意
,但它仍不失为一个能让您读取和写入任何 xml 编码的强大工具。

有关详细信息
microsoft msdn online library: xml dom reference(microsoft msdn 联机库
:xml dom 引用)


character encoding model(字符编码模型),作者:ken whistler 和 mark 
davis


iana character sets(iana 字符集)


http://www.ietf.org(英文)的 internet engineering task force (ietf) 提
供了 rfc 列表


microsoft msdn online library: compatibility issues with mixed 
environments(microsoft msdn 联机库:与混合环境的兼容性问题) 
--
                            oooo0    绝情空间,    
                            (   )            0oooo
                             \ (   源自苦爱. (   )
                              \_)             ) / 
                             ——我情依旧.   (_/  

※ 来源:.碧海青天 bbs.dlut.edu.cn.[FROM: tianwei]