《javascript高级程序设计》笔记(十八)

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文档进行转换。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。