javascript与XML
(一)浏览器对XML DOM的支持
DOM2级是第一个提到动态创建XML DOM概念的规范。DOM3级进一步增强XML DOM。
1.DOM2级核心
document.implementation.createDocument(namespaceUri, root, doctype);
通过javascript处理XML时通常只使用参数root,因为这个参数指定的是XML DOM文档元素的标签名。
//创建新的、文档元素为<root>的XML文档 var xmldom = document.implementation.createDocument("", "root", null); alert(xmldom.documentElement.tagName); //"root" var child = xmldom.createElement("child"); xmldom.documentElement.appendChild(child);
给命名空间传入空字符意味着未指定命名空间,给文档类型传入null意味着不指定文档类型。变量xmldom保存着DOM2级Document类型的实例。
这个例子显示了文档元素的标签名,又创建并给文档元素添加了一个新的子元素。
实际上往往是将某个DOM文件解析为DOM结构,或反之。
2.DOMParse类型
将XML解析为DOM文档
在解析XML之前,先要创建DOMParter实例,再调用parseFormString()方法。这个方法接收两个参数:要解析的XML字符串和内容类型(text/xml),返回值是Document的实例。
var xmldom = document.implementation.createDocument("", "root", null); alert(xmldom.documentElement.tagName); //"root" var child = xmldom.createElement("child"); xmldom.documentElement.appendChild(child);
只能解析格式良好的XML,不能把HTML解析为HTML文档。
IE9+ Firefox Safari Chrome Opera
3.XMLSerializer类型
将DOM文档序列化为XML字符串
先创建XMLSerializer的实例,再将文档传入其serializeToString()方法
var serializer = new XMLSerializer(); var xml = serializer.serializeToString(xmldom); alert(xml);
IE9+ Firefox Safari Chrome Opera
4.IE8及之前版本的XML
使用ActiveXObject构造函数并为其传入一个表示XML文档版本的字符串,最好用MSXML2.DOMDocument .6.0。
要解析XML字符串,先要创建一个DOM文档,然后调用loadXML()方法。
var xmldom = createDocument(); xmldom.loadXML("<root><child/></root>"); alert(xmldom.documentElement.tagName); //"root" alert(xmldom.documentElement.firstChild.tagName); //"child" var anotherChild = xmldom.createElement("child"); xmldom.documentElement.appendChild(anotherChild);
①序列化XML
IE每个DOM节点都有xml属性,保存着表示该节点的XML字符串
②加载XML文件
async属性:指定加载文档的方式,true表示异步,false表示同步,默认为true。
确定加载XML文档的方式后调用load()方法,接收一个参数即要加载的XML文件的URL。
var xmldom = createDocument(); xmldom.async = true; xmldom.load("example.xml");
异步加载XML文件需要为XML DOM文档的onreadystatechage事件指定事件处理程序,4状态表示XML文件完全加载完毕,而且全部解析为DOM文档。通过XML文件的readyState属性可以取得其状态。为onreadyStatechange事件指定事件处理程序的语句,必须放在调用load()方法的语句之前。在事件处理程序,必须使用XML文档变量的名称,不能用this对象。
5.跨浏览器处理XML
function parseXml(xml){ var xmldom = null; //检测DOMParser 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"){ //创建适当版本的XML文档 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; }
(二)浏览器对XPath的支持
是用来在DOM文档中查找节点的一种手段
1.DOM3级XPath
XPathEvaluator、XPathResult是最重要的类型,XPathEvaluator用于在特定的上下文对XPath表达式求值。
evaluate:在给定的上下文,基于特定的命名空间信息来对XPath求值。接收5个参数:Xpath表达式、上下文节点、命名空间求解器、返回结果的类型和保存结果的XPathResult对象(通常是null)。XPathResult.ORDERED_NODE_ITERATOR_TYPE是最常用的结果类型,表示返回匹配的节点集合,次序与文档一直。
如果指定的是快照结果类型,必须使用snapshotItem()方法和snapshotLength属性。
var result = xmldom.evaluate("employee/name", xmldom.documentElement, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); while (element) { message += serializer.serializeToString(element) + "\n"; count++; element = result.iterateNext() }
①单节点结果
指定XPathResult.FIRST_ORDERED_NODE_TYPE会返回第一个匹配的节点,可以通过结果的singleNodeValue属性访问该节点
②简单类型结果
通过XPathResult的布尔值、数值和字符串类型,可以取得简单的非节点数据类型,分别通过booleanValue、numberValue和stringValue返回一个值。
对于布尔值类型,如果至少一个节点与XPath的表达式匹配,则返回true。
var result = xmldom.evaluate("employee/name", xmldom.documentElement, null, XPathResult.BOOLEAN_TYPE, null); alert(result.booleanValue);
对于数值类型,必须在XPath表达式参数的位置上指定一个能返回数值的XPath函数,如计算给定模式匹配的所有节点数量的count()。
var result = xmldom.evaluate("count(employee/name)", xmldom.documentElement, null, XPathResult.NUMBER_TYPE, null); alert(result.numberValue);
③默认类型结果
使用XPathResult.ANY_TYPE可以自动确定返回结果的类型,要确定返回的是什么结果类型可以检测结果的resultType属性。
④命名空间支持
createNSResolver()来创建XPathNSResolver对象,这个方法接收一个参数,即文档中包含命名空间定义的节点。将nsresolver对象传入evaluate()后可以确保它能理解XPath表达式使用的wrox前缀。
var xmldom = (new DOMParser()).parseFromString("<?xml version=\"1.0\</wrox:books>", "text/xml"); var nsresolver = xmldom.createNSResolver(xmldom.documentElement); var result = xmldom.evaluate("wrox:book/wrox:author", xmldom.documentElement, nsresolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
或者定义一个函数,让它接收命名空间前缀,返回关联的URI。
2.IE中的XPath
IE9及之前版本使用XPath必须使用基于ActiveX的实现。
方法:selectSingeNode() :接收一个XPath模式,在找到匹配节点时返回第一个匹配的节点。
seclectNodes():返回与匹配的所有节点的NodeList。
IE对命名空间的支持
必须知道使用的命名空间,并按照格式创建字符串 "xmlns:prefix1=‘uri1‘ xmlns:prefix2=‘uri2‘ xmlns:prefix3=‘uri3‘"
必须将这个字符串传入setProperty(),接收两个参数,要设置的属性名和属性值。
3.跨浏览器使用XPath
(三)浏览器对XSLT的支持
XSLT是与XML相关的技术,利用XPath将文档从一种表现形式转换成另一种。
1.IE中的XSLT
①简单的XSLT转换
将XSLT和XML分别加到一个DOM文档,再使用transformNode()方法,接收一个参数:包含XSLT样式表的文档。调用transformNode()方法返回一个包含转回信息的字符串。
②复杂的XSLT转换
使用XSL模板和XSL处理器。第一部把XSLT样式表加载到一个线程安全的XML文档,可以通过使用MSXML2.FreeThreadedDOMDocument。然后将转换的节点指定给input属性,并调用transform()。
2.XSLTProcessor类型
加载两个DOM文档,分别基于XML和XSLT,然后创建新XSLTProcessor对象,并使用importStylesheet()方法为其指定一个XSLT。
如果要返回完整的DOM文档调用transformToDocument(),只要传入XML DOM,就可以将结果作为完全不同的DOM文档使用。调用transformTOFragment()得到一个文档片段对象。
transformToFragmentj()接收两个参数,要换货的XML DOM和应该拥有结果片段的文档,要将片段插入到页面,只要将ducoment作为第二个参数。
处理器创建一个由ducument对象拥有的片段,可以将返回的片段添加到页面已有的<div>元素。
var fragment = processor.transformToFragment(xmldom, document); var div = document.getElementById("divResult"); div.appendChild(fragment);
①使用参数
XSLTProcessor支持使用setParameter()设置XSLT的参数,这个方法接收三个参数:命名空间URI。参数的内部名称和要设置的值。必须在调用transformToDocument或transformToFragment()之前调用这个方法。
getParameter()和removeParameter()方法分别用于取得和移除当前参数的值。
②重置处理器
要调用reset方法,从处理器移除所有参数和样式表。
3.跨浏览器使用XSLT
跨浏览器兼容性最好的XSLT转换技术只能返回字符串,在IE只需在上下文节点上调用 transformNode(),其他浏览器要序列化transformToDocument()操作的结果。
使用IE的transformNode()可以确保不必使用线程安全的DOM文档进行转换。