现在,讨论过不同的字符编码方法之后,让我们来看看如何在 MSXML DOM 中加载 XML 文档,以及当碰到模糊编码的字符时,可能收到的出错消息的类型。加载 XML DOM 文档的两个主要方法是 LoadXML 方法和 Load 方法。
LoadXML 方法总是采用只在 UCS-2 或 UTF-16 中编码的 Unicode BSTR。如果将非有效的 Unicode BSTR 的内容传递给 LoadXML,则加载会失败。
Load 方法可将以下内容当作 VARIANT:
| Value | Description |
| URL | 如果 VARIANT 是 BSTR,则将其理解为 URL。 |
| VT_ARRAY | VT_UI1 | VARIANT 也可以是包含原始编码字节的 SAFEARRAY。 |
| IUnknown | 如果 VARIANT 是 IUnknown 接口,则 DOM 文档为 IStream、IPersistStream 和 IPersistStreamInit 调用 QueryInterface。 |
Load 方法实现以下算法,用于确定 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 | Description |
| ResponseXML | 表示由 MSXML DOM 分析器分析的响应实体(用与 Load 方法相同的规则)。 |
| ResponseText | 表示作为字串的响应实体。本方法盲目地解码从 UTF-8 收到的消息实体。这是一个已知问题,应在即将面市的 MSXML Web Release 中得到解决。 |
| ResponseBody | 表示作为无符号字节数组的响应实体。 |
| ResponseStream | 表示作为 IStream 接口的响应实体。 |
一旦加载了 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 编码文件的结果是:
$#@60;test$#@62;Ã¥$#@60;/test$#@62;
注意 上述例子只有当在浏览器以外的环境运行时,才有效。由于受到安全限制,在浏览器里调用 Save 方法将不会产生相同的结果。
尽管这看上去有点怪,但却是正确的。下列测试装载了用 UTF-8 编码的文件,并测试 UTF-8 是否被重新解码为 Unicode 字符值 229。它是:
var xmldoc = new ActiveXObject("Microsoft.XMLDOM")
xmldoc.load("foo.xml");
if (xmldoc.documentElement.text.charCodeAt(0) == 229)
{
WScript.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 编码的文件:
$#@60;?xml version="1.0" encoding="ISO-8859-1"?$#@62; $#@60;test$#@62;ålt;/test$#@62;
现在,小心不要被 XML 属性迷惑。XML 属性返回 Unicode 字串。如果在创建 ISO-8859-1 编码声明之后,调用 DOMDocument 对象上的 XML 属性,即可取回以下 Unicode 字串:
$#@60;?xml version="1.0"?$#@62; $#@60;test$#@62;ålt;/test$#@62;
请注意这里没有 ISO-8859-1 编码声明了。这是正常的。这样做的原因是使您可以转而用此字串调用 LoadXML,它会起作用。如果它不这么做,LoadXML 会失败并返回出错消息:“不支持从当前编码切换到指定的编码。”
结论但愿本文有助于解释字符编码的工作原理,特别是在 XML 和 MSXML DOM 中的工作原理。一旦您理解了字符集编码,它是相当简单的,而且 XML 是非常出色的,因为它在这方面未留有丝毫含糊的余地。尽管 MSXML DOM 有几处怪异需要密切留意,但它仍不失为一个能让您读取和写入任何 XML 编码的强大工具。
有关详细信息关注此文的读者还看过: