18.JavaScript 与XML(1)

JavaScript 与XML:几何时,XML 一度成为存储和通过因特网传输结构化数据的标准。透过XML 的发展,能够清晰地看到Web 技术发展的轨迹。DOM 规范的制定,不仅是为了方便在Web 浏览器中使用XML,也是为了在桌面及服务器应用程序中处理XML 数据。此前,由于浏览器无法解析XML 数据,很多开发人员都要动手编写自己的XML 解析器。而自从DOM 出现后,所有浏览器都内置了对XML 的原生支持(XML DOM),同时也提供了一系列相关的技术支持。

1 浏览器对XML DOM 的支持:在正式的规范诞生以前,浏览器提供商实现的XML 解决方案不仅对XML 的支持程度参差不齐,而且对同一特性的支持也各不相同。DOM2 级是第一个提到动态创建XML DOM 概念的规范。DOM3级进一步增强了XML DOM,新增了解析和序列化等特性。然而,当DOM3 级规范的各项条款尘埃落定之后,大多数浏览器也都实现了各自不同的解决方案。

  • DOM2 级核心:我们在第12 章曾经提到过,DOM2级在document.implementation 中引入了createDocument()方法。IE9+、Firefox、Opera、Chrome 和Safari 都支持这个方法。想一想,或许你还记得可以在支持DOM2级的浏览器中使用以下语法来创建一个空白的XML 文档:

var xmldom = document.implementation.createDocument(namespaceUri, root, doctype);

在通过JavaScript 处理XML 时,通常只使用参数root,因为这个参数指定的是XML DOM 文档元素的标签名。而namespaceUri 参数则很少用到,原因是在JavaScrip 中管理命名空间比较困难。最后,doctype 参数用得就更少了。

因此,要想创建一个新的、文档元素为<root>的XML 文档,可以使用如下代码:

var xmldom = document.implementation.createDocument("", "root", null);
alert(xmldom.documentElement.tagName); //"root"
var child = xmldom.createElement("child");
xmldom.documentElement.appendChild(child);

这个例子创建了一个XML DOM文档,没有默认的命名空间,也没有文档类型。但要注意的是,尽管不需要指定命名空间和文档类型,也必须传入相应的参数。具体来说,给命名空间URI 传入一个空字符串,就意味着未指定命名空间,而给文档类型传入null,就意味着不指定文档类型。变量xmldom中保存着一个DOM2 级Document 类型的实例,带有第12 章讨论过的所有DOM方法和属性。我们这个例子显示了文档元素的标签名,然后又创建并给文档元素添加了一个新的子元素。

要检测浏览器是否支持DOM2 级XML,可以使用下面这行代码:

var hasXmlDom = document.implementation.hasFeature("XML", "2.0");

在实际开发中,很少需要从头开始创建一个XML 文档,然后再使用DOM 文档为其添加元素。更常见的情况往往是将某个XML 文档解析为DOM 结构,或者反之。由于DOM2 级规范没有提供这种功能,因此就出现了一些事实标准。

  • DOMParser类型:为了将XML 解析为DOM文档,Firefox 引入了DOMParser 类型;后来,IE9、Safari、Chrome 和Opera 也支持了这个类型。在解析XML 之前,首先必须创建一个DOMParser 的实例,然后再调用parseFromString()方法。这个方法接受两个参数:要解析的XML 字符串和内容类型(内容类型始终都应该是"text/xml")。返回的值是一个Document 的实例。来看下面的例子。

var parser = new DOMParser();
var xmldom = parser.parseFromString("<root><child/></root>", "text/xml");
alert(xmldom.documentElement.tagName); //"root"
alert(xmldom.documentElement.firstChild.tagName);           //"child"
var anotherChild = xmldom.createElement("child");
xmldom.documentElement.appendChild(anotherChild);
var children = xmldom.getElementsByTagName("child");
alert(children.length);                                     //2

在这个例子中,我们把一个简单的XML 字符串解析成了一个DOM文档。解析得到的DOM 结构以<root>作为其文档元素,该元素还有一个<child>子元素。此后,就可以使用DOM 方法对返回的这个文档进行操作了。

DOMParser 只能解析格式良好的XML,因而不能把HTML 解析为HTML 文档。在发生解析错误时, 仍然会从parseFromString() 中返回一个Document 对象, 但这个对象的文档元素是<parsererror>,而文档元素的内容是对解析错误的描述。下面是一个例子。

<parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">
XML Parsing Error: no element found Location: file:///I:/My%20Writing/My%20Books/
Professional%20JavaScript/Second%20Edition/Examples/Ch15/DOMParserExample2.htm Line
Number 1, Column 7: 
    <sourcetext> & lt;root & gt; ------^</sourcetext >
< /parsererror>

Firefox 和Opera 都会返回这种格式的文档。Safari 和Chrome 返回的文档也包含<parsererror>元素,但该元素会出现在发生解析错误的地方。IE9 会在调用parseFromString()的地方抛出一个解析错误。由于存在这些差别,因此确定是否发生解析错误的最佳方式就是,使用一个try-catch 语句块,如果没有错误,则通过getElementsByTagName()来查找文档中是否存在<parsererror>元素,如下面的例子所示。

var parser = new DOMParser(),
    xmldom,errors;
try {
    xmldom = parser.parseFromString("<root>", "text/xml");
    errors = xmldom.getElementsByTagName("parsererror");
    if (errors.length > 0){
        throw new Error("Parsing error!");
    }
} catch (ex) {
    alert("Parsing error!");
}

这例子显示,要解析的字符串中缺少了闭标签</root>,而这会导致解析错误。在IE9+中,此时会抛出错误。在Firefox 和Opera 中,文档元素将是<parsererror>,而在Safari 和Chrome 中,<parsererror>是<root>的第一个子元素。调用getElementsByTagName("parsererror")能够应对这两种情况。如果这个方法返回了元素,就说明有错误发生,继而通过一个警告框显示出来。当然,你还可以更进一步,从错误元素中提取出错误信息。

  • XMLSerializer类型:在引入DOMParser 的同时,Firefox 还引入了XMLSerializer 类型,提供了相反的功能:将DOM
    文档序列化为XML 字符串。后来,IE9+、Opera、Chrome 和Safari 都支持了XMLSerializer。

要序列化DOM 文档,首先必须创建XMLSerializer 的实例,然后将文档传入其serializeToString ()方法,如下面的例子所示。

var serializer = new XMLSerializer();
var xml = serializer.serializeToString(xmldom);
alert(xml);

但是,serializeToString()方法返回的字符串并不适合打印,因此看起来会显得乱糟糟的。

XMLSerializer 可以序列化任何有效的DOM 对象,不仅包括个别的节点,也包括HTML 文档。将HTML 文档传入serializeToString()以后,HTML 文档将被视为XML 文档,因此得到的代码也将是格式良好的。

如果将非DOM 对象传入serializeToString(),会导致错误发生。

  • IE8 及之前版本中的XML:事实上,IE 是第一个原生支持XML 的浏览器,而这一支持是通过ActiveX 对象实现的。为了便于桌面应用程序开发人员处理XML,微软创建了MSXML 库;但微软并没有针对JavaScript 创建不同的对象,而只是让Web 开发人员能够通过浏览器访问相同的对象。

第8 章曾经介绍过ActiveXObject 类型,通过这个类型可以在JavaScript 中创建ActiveX 对象的实例。同样,要创建一个XML 文档的实例,也要使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值