41-JavaScript高级程序设计-JavaScript与XML

一、浏览器对 XML DOM 的支持

1. DOM2 级核心

document.implementation 引入方法 createDocument()。
浏览器支持:IE9+、Firefox、Opera、Chrome 和 Safari。
var xmldom = document.implementation.createDocument(namespaceUri, root, doctype);
创建一个新的、文档元素为 <root> 的 XML 文档:
var xmldom = document.implementation.createDocument("", "root", null);
检测浏览器是否支持 DOM2 级 XML:
var hasXmlDom = document.implementation.hasFeature("XML", "2.0");
实际开发中,很少需要从头开始创建一个 XML 文档,然后再使用 DOM 文档为其添加元素。更常见的情况往往是将某个 XML 文档解析为 DOM 结构,或者反之。

2. DOMParser 类型

在解析 XML 之前,首先必须创建一个 DOMParser 的实例,然后再调用 parseFromString() 方法。
两个参数:要解析的 XML 字符串,内容类型(内容类型始终都应该是 “text/xml” )。
返回值:一个 Document 的实例。

var parser = new DOMParser();
var xmldom = parser.parseFromString("<root><child/></root>", "text/xml");

DOMParser 只能解析格式良好的 XML(不能把 HTML 解析为 HTML 文档)。
在发生解析错误时,仍然会从 parseFromString() 中返回一个 Document 对象,对象的文档元素是 <parsererror> ,文档元素的内容是对解析错误的描述。
Firefox和 Opera都会返回这种格式的文档。Safari和 Chrome返回的文档也包含 <parsererror> 元素,但该元素会出现在发生解析错误的地方。IE9 会在调用 parseFromString() 的地方抛出一个解析错误。

3. XMLSerializer 类型

XMLSerializer 类型,提供了相反的功能:将 DOM文档序列化为 XML 字符串。
浏览器支持:Firefox、IE9+、Opera、Chrome 和 Safari。

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

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

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

4. IE8 及之前版本中的XML

IE 是第一个原生支持 XML 的浏览器,是通过 ActiveX 对象实现的。
创建一个 XML 文档的实例:使用 ActiveXObject 构造函数,传入一个表示 XML 文档版本的字符串。
XML 文档版本有 6 种,只推荐使用 MSXML2.DOMDocument.6.0(最新最可靠的版本) 或 MSXML2.DOMDocument.3.0 (大多数 Windows 操作系统都支持的版本)。

解析 XML 字符串,首先必须创建一个 DOM 文档,然后调用 loadXML() 方法。
新创建的 XML 文档完全是一个空文档,因而不能对其执行任何操作。为 loadXML() 方法传入的 XML 字符串经解析之后会被填充到 DOM 文档中。

var xmldom = createDocument();
xmldom.loadXML("<root><child/></root>");

如果解析过程中出错,可以在 parseError 属性(对象)中找到错误消息。有多个属性:
errorCode:错误类型的数值编码;在没有发生错误时值为 0。
filePos:文件中导致错误发生的位置。
line:发生错误的行。
linepos:发生错误的行中的字符。
reason:对错误的文本解释。
srcText:导致错误的代码。
url:导致错误的文件的 URL(如果有这个文件的话)。
parseError 的 valueOf() 方法返回 errorCode 的值。

序列化 XML:IE 将序列化 XML 的能力内置在了 DOM 文档中。每个 DOM 节点都有一个 xml 属性,其中保存着表示该节点的 XML 字符串。

加载 XML 文件:IE 中的 XML 文档对象也可以加载来自服务器的文件。
(1)要加载的 XML文档必须与页面中运行的 JavaScript 代码来自同一台服务器。
(2)加载文档的方式也可以分为同步和异步两种。要指定加载文档的方式,可以设置 async 属性,true 表示异步,false 表示同步(默认值为 true )。
在确定了加载 XML 文档的方式后,调用 load() 可以启动下载过程。
一个参数:要加载的 XML 文件的 URL。
在异步加载 XML 文件的情况下,需要为 XML DOM文档的 onreadystatechange 事件指定处理程序。有 4 个就绪状态(readyState) 1/2/3/4,一般关注状态 4 即可。

5. 跨浏览器处理XML

通过能力检测来确定要使用的 XML 解析方式。
解析 XML:

function parseXml(xml){
  var xmldom = null;
  if (typeof DOMParser != "undefined"){
    xmldom = (new DOMParser()).parseFromString(xml, "text/xml");
    var errors = xmldom.getElementsByTagName("parsererror");
    if (errors.length){
      throw new Error("XML parsing error:" + errors[0].textContent);
    }
  } else if (typeof ActiveXObject != "undefined"){
    xmldom = createDocument();
    xmldom.loadXML(xml);
    if (xmldom.parseError != 0){
      throw new Error("XML parsing error: " + xmldom.parseError.reason);
    }
  } else {
    throw new Error("No XML parser available.");
  }
  return xmldom;
}

调用使用 try-catch 语句,以防发生错误。

序列化 XML:

function serializeXml(xmldom){
  if (typeof XMLSerializer != "undefined"){
    return (new XMLSerializer()).serializeToString(xmldom);
  } else if (typeof xmldom.xml != "undefined"){
    return xmldom.xml;
  } else {
    throw new Error("Could not serialize XML DOM.");
  }
}

调用不必使用 try-catch 语句,直接调用即可。

二、浏览器对 XPath 的支持

XPath 是设计用来在 DOM 文档中查找节点的一种手段。

1. DOM3 级XPath

确定浏览器是否支持DOM3级 XPath:
var supportsXPath = document.implementation.hasFeature("XPath", "3.0");
DOM3 级 XPath 规范定义的类型中,最重要的两个类型是 XPathEvaluator 和 XPathResult 。

XPathEvaluator:用于在特定的上下文中对 XPath 表达式求值。
3个方法:
createExpression(expression, nsresolver):将 XPath 表达式及相应的命名空间信息转换成一个 XPathExpression ,这是查询的编译版。在多次使用同一个查询时很有用。
createNSResolver(node):根据 node 的命名空间信息创建一个新的 XPathNSResolver 对象。在基于使用命名空间的 XML 文档求值时,需要使用 XPathNSResolver 对象。
evaluate(expression, context, nsresolver, type, result):在给定的上下文中,基于特定的命名空间信息来对 XPath 表达式求值。剩下的参数指定如何返回结果。

evaluate() 最常用,5 个参数:XPath 表达式、上下文节点、命名空间求解器、返回结果的类型和保存结果的 XPathResult 对象(通常是 null ,因为结果也会以函数值的形式返回)。
如果没有节点匹配 XPath 表达式,evaluate() 返回 null;否则返回一个 XPathResult 对象。这个 XPathResult 对象带有的属性和方法,可以用来取得特定类型的结果。如果节点是一个节点迭代器,无论是次序一致还是次序不一致的,都必须要使用 iterateNext() 方法从节点中取得匹配的节点。在没有更多的匹配节点时,iterateNext() 返回 null 。

2. IE中的XPath

IE 对 XPath 的支持是内置在基于 ActiveX 的 XML DOM 文档对象中的,没有使用 DOMParser 返回的 DOM 对象。

两个方法:selectSingleNode() 和 selectNodes()。
selectSingleNode():接收一个 XPath 模式,在找到匹配节点时返回第一个匹配的节点,如果没有找到匹配的节点就返回 null。
selectNodes():接收一个 XPath 模式作为参数,返回与模式匹配的所有节点的 NodeList (如果没有匹配的节点,则返回一个包含零项的 NodeList )。

3. 跨浏览器使用XPath

IE 对 XPath 功能的支持有限,因此跨浏览器 XPath 只能保证达到 IE 支持的功能。
即 在其他使用 DOM3 级 XPath 对象的浏览器中,重新创建 selectSingleNode() 和 selectNodes() 方法。

三、浏览器对 XSLT 的支持

XSLT 是与 XML 相关的一种技术,它利用 XPath 将文档从一种表现形式转换成另一种表现形式。
与 XML 和 XPath 不同,XSLT 没有正式的 API,在正式的 DOM 规范中也没有它的位置。

1. IE中的XSLT

与 IE对其他 XML功能的支持一样,它对 XSLT的支持也是通过 ActiveX对象实现的。
1.简单的 XSLT 转换
使用 XSLT 样式表转换 XML 文档的最简单方式,就是将它们分别加到一个 DOM 文档中,然后再使用 transformNode() 方法。
一个参数:包含 XSLT 样式表的文档。返回值:一个包含转换信息的字符串。

//加载 XML 和 XSLT(仅限于 IE)
xmldom.load("employees.xml");
xsltdom.load("employees.xslt");
//转换
var result = xmldom.transformNode(xsltdom);

2.复杂的 XSLT 转换
使用 XSL 模板和 XSL 处理器。
第一步是要把 XSLT 样式表加载到一个线程安全的 XML文档中。在创建并加载了自由线程的 DOM 文档之后,必须将它指定给一个 XSL 模板,这也是一个 ActiveX 对象。在创建了 XSL 处理器之后,必须将要转换的节点指定给 input 属性。这个值可以是一个文档,也可以是文档中的任何节点。然后,调用 transform() 方法即可执行转换并将结果作为字符串保存在 output 属性中。
这些代码实现了与 transformNode() 相同的功能。

2. XSLTProcessor 类型

XSLTProcessor 类型使用 XSLT 转换 XML 文档,其方式与在 IE 中使用 XSL 处理器类似。
浏览器支持:Firefox、Chrome、Safari 和 Opera。

第一步加载两个 DOM 文档,一个基于 XML,另一个基于 XSLT。
创建一个新 XSLTProcessor 对象,并使用 importStylesheet() 方法为其指定一个 XSLT。
最后一步就是执行转换。这一步有两种不同的方式。
方式1:如果想返回一个完整的 DOM 文档,可以调用 transformToDocument()。
方式2:通过调用 transformToFragment() 可以得到一个文档片段对象。使用场景:想把返回的结果添加到另一个 DOM文档中。

1.使用参数
setParameter():设置 XSLT的参数
三个参数:命名空间URI、参数的内部名称和要设置的值。
通常,命名空间 URI 都是 null,而内部名称就是参数的名称。必须在调用 transformToDocument() 或 transformToFragment() 之前调用这个方法。

getParameter() 和 removeParameter():分别用于取得和移除当前参数的值。
这两个方法都要接受命名空间参数(同样,通常是 null )和参数的内部名称。

2.重置处理器
每个 XSLTProcessor 的实例都可以重用,以便使用不同的 XSLT 样式表执行不同的转换。
reset():会从处理器中移除所有参数和样式表。

3. 跨浏览器使用XSLT

IE 对 XSLT 转换的支持与 XSLTProcessor 的区别实在太大,因此要想重新实现二者所有这方面的功能并不现实。
因此,跨浏览器兼容性最好的 XSLT 转换技术,只能是返回结果字符串。
为此在 IE 中只需在上下文节点上调用 transformNode() 即可,而在其他浏览器中则需要序列化 transformToDocument() 操作的结果。

总结:本章内容我目前使用不多,只是按红宝书略作了下笔记,感兴趣的自己结合书中实例学习。


上一篇:40-JavaScript高级程序设计-错误处理与调试
下一篇:42-JavaScript高级程序设计-E4X

全书整理版:《Javascript高级程序设计》第3版(总结版)


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值