处理XML
浏览器对XML DOM的支持
在正式标准问世前,很多浏览器就开始实现自己的XML解析方案,不同浏览器对标准的支持不仅有级别上的差异,也有实现上的差异;DOM Level 3增加了解析和序列化的能力;在DOM Level 3制定完成时,大多数浏览器也已实现了自己的解析方案
DOM Level 2 Core
12章中所述,DOM Level 2 增加了document.implementation的createDocument()方法,用于创建XML文档
let xmldom = document.implementation.createDocument(namespaceUrl, root, doctype);
在js中处理XML时,root参数通常只会用一次,因为这个参数定义的是XML DOM中document的标签名;namespaceUrl参数用的更少,因为在js中很难管理命名空间;doctype参数则更少用,所以我们一般我们这么创建:
let xmldom = document.implementation.createDocument("", "root", null);
//创建标签名为<root>的新XML文档
let child = xmldom.createElement('child');
xmldom.documentElement.appendChild(child);
检查浏览器是否支持DOM Level 2 XML,可以使用如下方法:
let hasXmlDom = document.implementation.hasFeature('XML', '2.0');
DOMParser类型
该类型实例可用于把XML解析为DOM文档;先创建实例,然后调用parseFromString()方法;该方法接收两个参数:要解析的XML字符串和内容类型(始终应该是“text/html”),返回值是Document的实例
let parser = new DOMParser();
let xmldom = parser.parseFromString("<root><child></root>", "text/xml");
xmldom.documentElement.tagName; //"root"
xmldom.documentElement.firstChild.tagName; //"child"
得到的对象可以使用DOM方法与其交互
DOMParser只能解析格式良好的XML,因此不能把HTML解析为HTML;发生解析错误时,不同浏览器处理机制不一样,最好使用try/catch来判断是否发生错误,如果没有错误则通过getElementsByTagName()方法查找文档中是否有<parsererror>元素
XMLSerializer类型
该类型实例用于把DOM文档序列化为XML字符串;先创建实例,然后把文档传给serializeToString()方法
let serializer = new XMLSerializer();
let xml = serializer.serializeToString(xmldom);
console.log(xml); //打印结果看起来有点困难,因为格式不好
XMLSerializer能够序列化任何有效的DOM对象,包括个别节点和HTML文档,在把HTML文档传给serializeToString()时,这个文档会被当成XML文档,得到的结果是格式良好的
传入上述方法非DOM对象,会导致抛出错误
浏览器对XPath的支持
XPath是为了在DOM文档中定位特定节点而创建的,它对XML处理很重要
DOM Level 3 XPath
该规范定义了接口,用于在DOM中求值XPath表达式;要确定浏览器是否支持DOM Level 3 XPath,使用以下代码:
let supportsXPath = document.implementation.hasFeature('XPath', '3.0');
在这个规范中最重要的两个类型是:XPathEvaluator和XPathResult
前者用于在特定上下文中求值XPath表达式,包含三个方法:
createExpression(expression, nsresolver),根据XPath表达式以及相应的命名空间计算得到一个XPathExpression,这是查询的编译版本
createNSResolver(node),基于node的命名空间创建新的XPathNSResolver对象;当对使用名称空间的XML文档求值时,需要XPathNSResolver对象
evaluate(expression, context, nsresolver, type, result),根据给定的上下文和命名空间对XPath进行求值,其他参数表示如何返回结果
Document类型通常是通过XPathEvaluator接口实现的,因此可以创建XPathEvaluator的实例,或使用Document实例上的方法
使用最频繁的方法是:evaluate(),该方法接收五个参数:XPath表达式、上下文节点、命名空间解析器、返回的结果类型、XPathResult对象(用于填充结果,通常是null,因为结果也可能是函数);第三个参数只在XML代码使用XML命名空间的情况下有必要,如果没有使用命名空间,这个参数也应该是null;第四个参数可以是十个值(参考红宝书p697)
返回的XPathResult对象上有相应的属性和方法用于获取特定类型的结果
单个节点结果
简单类型结果
默认类型结果
以上三条参考红宝书p698
命名空间支持
对于使用命名空间的XML文档,必须告诉XPathEvaluator命名空间信息,才能进行正确的求值
第一种方法是通过createNSResolver()方法创建XPathNSResolver对象,该方法接收一个参数:包含命名空间定义的文档节点;然后这个对象就可以在evaluate()方法使用
第二种方法是定义一个接收命名空间的前缀并返回相应的URL的函数
let nsresolver = xmldom.createNSResolver(xmldom.documentElement);
let result = xmldom.evaluate("wrox:book/wrox:author", xmldom.documentElement, nsresolver, ..., null);
let nsresolver = function(prefix) {
switch(prefix) {
case "wrox": return "http://www.wrox.com/";
}
}
let result = xmldom.evaluate("wrox:book/wrox:author", xmldom.documentElement, nsresolver, ..., null);
浏览器对XSLT的支持
可扩展样式表语言转换(XSLT)是与XML相伴的一种技术,可以利用XPath将一种文档转换为另一种文档表示
因为正式的DOM没有涵盖它,没有正式API,各个浏览器都有自己的实现方式
所以这里不过多介绍,详情查看红宝书p701