美文网首页JavaScript < ES5、ES6、ES7、… >
JavaScript 高级程序设计(第18章 JavaScrip

JavaScript 高级程序设计(第18章 JavaScrip

作者: yinxmm | 来源:发表于2018-08-19 14:29 被阅读14次

    第18章 JavaScript 与 XML

    1. 浏览器对 XML DOM 的支持

    (1) DOM2 级核心

    * 支持 DOM2 级的浏览器中使用以下语法来创建一个空白的 XML 文档:

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

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

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

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

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

    (2) DOMParser类型

    1. 在解析 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);
    var anotherChild = xmldom.createElement("child");
    xmldom.documentElement.appendChild(anotherChild);
    var children = xmldom.getElementsByTagName("child");
    alert(children.length);     //2
    
    1. DOMParser 只能解析格式良好的 XML,因而不能把 HTML 解析为 HTML 文档。在发生解析错误 时,仍然会从 parseFromString()中返回一个 Document 对象,但这个对象的文档元素是 <parsererror>,而文档元素的内容是对解析错误的描述。

    (3)XMLSerializer类型

    XMLSerializer 类型将 DOM 文档序列化为 XML 字符串。

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

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

    (4) IE8 及之前版本中的XML

    1. IE 是第一个原生支持 XML 的浏览器,而这一支持是通过 ActiveX 对象实现的。
    2. ActiveXObject 类型可以在 JavaScript 中创建 ActiveX 对象的实例。创建一个 XML 文档的实例,也要使用 ActiveXObject 构造函数并为其传入一个表示 XML 文档版本的字符串
    • 通过尝试创建每个版本的实例并观察是否有错误发生,可以确定哪个版本可用。
    function createDocument(){
            if (typeof arguments.callee.activeXString != "string"){
            var versions = ["MSXML2.DOMDocument.6.0", "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument"],i, len;
            for (i=0,len=versions.length; i < len; i++){
                try {
                    new ActiveXObject(versions[i]);
                    arguments.callee.activeXString = versions[i];
                    break;
                } catch (ex){ 
                    //跳过
                } 
            }
            }
        return new ActiveXObject(arguments.callee.activeXString);
    }
    
    • 要解析 XML 字符串,首先必须创建一个 DOM 文档,然后调用 loadXML()方法
    var xmldom = createDocument();
    xmldom.loadXML("<root><child/></root>");
    alert(xmldom.documentElement.tagName);      //"root"
    alert(xmldom.documentElement.firstChild.tagName);
    var anotherChild = xmldom.createElement("child");
    xmldom.documentElement.appendChild(anotherChild);
    var children = xmldom.getElementsByTagName("child");
    alert(children.length);   //2
    
    • 如果解析过程中出错,可以在 parseError 属性中找到错误消息。

    (1) errorCode:错误类型的数值编码;在没有发生错误时值为 0。
    (2) filePos:文件中导致错误发生的位置。
    (3) line:发生错误的行。
    (4) linepos:发生错误的行中的字符。
    (5) reason:对错误的文本解释。
    (6) srcText:导致错误的代码。
    (7) url:导致错误的文件的 URL(如果有这个文件的话)

    if (xmldom.parseError != 0){
        alert("An error occurred:\nError Code: "
            + xmldom.parseError.errorCode + "\n"
            + "Line: " + xmldom.parseError.line + "\n"
            + "Line Pos: " + xmldom.parseError.linepos + "\n"
            + "Reason: " + xmldom.parseError.reason);
    }
    
    * 序列化 XML

    每个 DOM 节点都有一个 xml 属性,其中保存着
    表示该节点的 XML 字符串。

    alert(xmldom.xml);
    
    * 加载 XML 文件
    1. IE 中的 XML 文档对象也可以加载来自服务器的文件。加载文档的方式也可以分为同步和异步两种。要指定加载文档的方式,可以设置async 属性,true 表示异步,false 表示同步(默认值为 true)。
    2. 在确定了加载 XML 文档的方式后,调用load()可以启动下载过程。这个方法接受一个参数,即要加载的 XML 文件的 URL。
    1. 同步方式下,调用 load()后可以立即检测解析错误并执行相关的 XML 处理。
    var xmldom = createDocument(); 
    xmldom.async = false;
    xmldom.load("example.xml");
    if (xmldom.parseError != 0){ 
    //处理错误
    } else {
    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
        alert(xmldom.xml);
    }
    

    异步加载 XML 文件的情况下,需要为 XML DOM 文档的 onreadystatechange 事件指定处理程序。

    4 个就绪状态(ready state):

    1:DOM 正在加载数据。
    2:DOM 已经加载完数据。
    3:DOM 已经可以使用,但某些部分可能还无法访问。
    4:DOM 已经完全可以使用。

    XML 文档的 readyState 属性可以取得其就绪状态。

    var xmldom = createDocument();
    xmldom.async = true;
    xmldom.onreadystatechange = function(){
        if (xmldom.readyState == 4){
            if (xmldom.parseError != 0){
                alert("An error occurred:\nError Code: "
                      + xmldom.parseError.errorCode + "\n"
                      + "Line: " + xmldom.parseError.line + "\n"
                      + "Line Pos: " + xmldom.parseError.linepos + "\n"
                      + "Reason: " + xmldom.parseError.reason);
             } else {
                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
                alert(xmldom.xml);
            }
        }
    };
    xmldom.load("example.xml");
    

    (5) 跨浏览器处理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;
    }
    
    //在使用这个函数解析 XML 字符串时,应该将它放在 try-catch 语句当中,以防发生错误。
    var xmldom = null;
    try {
        xmldom = parseXml("<root><child/></root>");
    } catch (ex){
        alert(ex.message);
    } 
    //进一步处理
    
    *序列化 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.");
        }
    }
    
    var xml = serializeXml(xmldom);
    

    2. 浏览器对 XPath 的支持

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

    (1) DOM3 级XPath

    • 确定某浏览器是否支持 DOM3级 XPath:
    var supportsXPath = document.implementation.hasFeature("XPath", "3.0");
    
    XPathEvaluator用于在特定的上下文中对 XPath 表达式求值。这个类型有下列 3 个方法。
    1. createExpression(expression, nsresolver):将 XPath 表达式及相应的命名空间信息转 换成一个 XPathExpression,这是查询的编译版。在多次使用同一个查询时很有用。
    2. createNSResolver(node):根据 node 的命名空间信息创建一个新的 XPathNSResolver 对 象。在基于使用命名空间的 XML 文档求值时,需要使用 XPathNSResolver 对象。
    3. evaluate(expression, context, nsresolver, type, result):在给定的上下文中, 基于特定的命名空间信息来对 XPath 表达式求值。剩下的参数指定如何返回结果。
    1. evaluate()这个方法接收5 个参数:XPath 表达式、上下文节点、命名空间求解器、返回结果的类型和保存结果的 XPathResult 对象(通常是 null,因为结果 也会以函数值的形式返回)。

    (1) 第三个参数(命名空间求解器)只在 XML 代码中使用了 XML 命名空间时有必要指定;如果 XML 代码中没有使用命名空间,则这个参数应该指定为 null。
    (2) 第四个参数(返回结果的类型)的取值范围是下列常量之一。

    • XPathResult.ANY_TYPE:返回与 XPath 表达式匹配的数据类型。
    • XPathResult.NUMBER_TYPE:返回数值。
    • XPathResult.STRING_TYPE:返回字符串值。
    • XPathResult.BOOLEAN_TYPE:返回布尔值。
    • XPathResult.UNORDERED_NODE_ITERATOR_TYPE:返回匹配的节点集合,但集合中节点的次 序不一定与它们在文档中的次序一致。
    • XPathResult.ORDERED_NODE_ITERATOR_TYPE:返回匹配的节点集合,集合中节点的次序与 它们在文档中的次序一致。这是最常用的结果类型。
    • XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:返回节点集合的快照,由于是在文档外部 捕获节点,因此对文档的后续操作不会影响到这个节点集合。集合中节点的次序不一定与它们 在文档中的次序一致。
    • XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:返回节点集合的快照,由于是在文档外部捕 获节点,因此对文档的后续操作不会影响到这个节点集合。集合中节点的次序与它们在文档中 的次序一致。
    • XPathResult.ANY_UNORDERED_NODE_TYPE:返回匹配的节点集合,但集合中节点的次序不 一定与它们在文档中的次序一致。
    • XPathResult.FIRST_ORDERED_NODE_TYPE:返回只包含一个节点的节点集合,包含的这个 节点就是文档中第一个匹配的节点。

    在 Firefox、Safari、Chrome 和 Opera 中,Document 类型通常都是与 XPathEvaluator 接口一起实现的。换句话说,在这些浏览器中,既可以创建 XPathEvaluator 的新实例,也可以使用 Document 实例中的方法(XML 或 HTML 文档均是如此)。

    var result = xmldom.evaluate("employee/name", xmldom.documentElement, null,XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
    if (result !== null) {
        var node = result.iterateNext();
        while(node) {
            alert(node.tagName);
            node = node.iterateNext();
        }
    }
    

    如果指定的是快照结果类型(不管是次序一致还是次序不一致的),就必须使用snapshotItem() 方法和 snapshotLength 属性

    var result = xmldom.evaluate("employee/name", xmldom.documentElement, null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    if (result !== null) {
        for (var i=0, len=result.snapshotLength; i < len; i++) {
            alert(result.snapshotItem(i).tagName);
        }
    }
    
    *单节点结果

    指定常量XPathResult.FIRST_ORDERED_NODE_TYPE会返回第一个匹配的节点,可以通过结果的singleNodeValue 属性来访问该节点。

    var result = xmldom.evaluate("employee/name", xmldom.documentElement, null,XPathResult.FIRST_ORDERED_NODE_TYPE, null);
    if (result !== null) {
            alert(result.singleNodeValue.tagName);
    }
    
    *简单类型结果

    XPathResult的布尔值、数值和 字符串类型。这几个结果类型分别会通过 booleanValue、numberValue 和 stringValue 属性返回一个值。

    1. 对于布尔值类型,如果至少有一个节点与 XPath 表达式匹配,则求值结果返回 true,否则 返回 false。
    var result = xmldom.evaluate("employee/name", xmldom.documentElement, null,XPathResult.BOOLEAN_TYPE, null);
    alert(result.booleanValue);
    
    1. 数值类型,必须在 XPath 表达式参数的位置上指定一个能够返回数值的 XPath 函数,如果使用这个方法的时候没有指定 的 XPath 函数,那么 numberValue 的值将等于 NaN。
    var result = xmldom.evaluate("count(employee/name)", xmldom.documentElement,null, XPathResult.NUMBER_TYPE, null);
    alert(result.numberValue);
    
    1. 对于字符串类型,evaluate()方法会查找与 XPath 表达式匹配的第一个节点,然后返回其第一个 子节点的值(实际上是假设第一个子节点为文本节点)。如果没有匹配的节点,结果就是一个空字符串。
    var result = xmldom.evaluate("employee/name", xmldom.documentElement, null, XPathResult.STRING_TYPE, null);
    alert(result.stringValue);
    
    *默认类型结果

    使用 XPathResult.ANY_TYPE 常量可以自动确定返回结果的类型。要确定返回的是什么结 果类型,可以检测结果的 resultType 属性

    var result = xmldom.evaluate("employee/name", xmldom.documentElement, null,
                                          XPathResult.ANY_TYPE, null);
        if (result !== null) {
            switch(result.resultType) {
                case XPathResult.STRING_TYPE:
                //处理字符串类型 
                break;
                case XPathResult.NUMBER_TYPE: 
                //处理数值类型
                break;
                case XPathResult.BOOLEAN_TYPE: 
                //处理布尔值类型
                break;
                case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: 
                //处理次序不一致的节点迭代器类型
                break;
                default: 
                //处理其他可能的结果类型
            }
    }
    
    *命名空间支持
    • 对于利用了命名空间的 XML 文档,XPathEvaluator 必须知道命名空间信息,然后才能正确地进行求值。
    <?xml version="1.0" ?>
    <wrox:books xmlns:wrox="http://www.wrox.com/">
    <wrox:book>
    <wrox:title>Professional JavaScript for Web Developers</wrox:title> <wrox:author>Nicholas C. Zakas</wrox:author>
        </wrox:book>
        <wrox:book>
            <wrox:title>Professional Ajax</wrox:title>
            <wrox:author>Nicholas C. Zakas</wrox:author>
            <wrox:author>Jeremy McPeak</wrox:author>
            <wrox:author>Joe Fawcett</wrox:author>
        </wrox:book>
    </wrox:books>
    

    在这个 XML 文档中,所有元素定义都来自 http://www.wrox.com/命名空间,以前缀 wrox 标识。 如果要对这个文档使用 XPath,就需要定义要使用的命名空间;否则求值将会失败。

    处理命名空间的方法:

    1. 通过 createNSResolver()来创建 XPathNSResolver 对象。这个 方法接受一个参数,即文档中包含命名空间定义的节点。
    var nsresolver = xmldom.createNSResolver(xmldom.documentElement);
    var result = xmldom.evaluate("wrox:book/wrox:author",
    xmldom.documentElement, nsresolver,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    alert(result.snapshotLength);
    
    1. 定义一个函数,让它接收一个命名空间前缀,返回关联的 URI。
    var nsresolver = function(prefix){
        switch(prefix){
            case "wrox": return "http://www.wrox.com/";
            //其他前缀 
        }
    };
    
    var result = xmldom.evaluate("count(wrox:book/wrox:author)", xmldom.documentElement, nsresolver, XPathResult.NUMBER_TYPE, null);
    alert(result.numberValue);
    

    (2) IE中的XPath

    1. selectSingleNode()方法接受一个 XPath 模式,在找到匹配节点时返回第一个匹配的节点,如果没有 找到匹配的节点就返回 null。
    var element = xmldom.documentElement.selectSingleNode("employee/name");
    if (element !== null){
        alert(element.xml);
    }
    
    1. selectNodes()也接收一个 XPath 模式作为参数,但它返回与模式匹配的所有节点的 NodeList(如果没有匹配的节点,则返回一个包含零项的 NodeList)。
    var elements = xmldom.documentElement.selectNodes("employee/name");
    alert(elements.length);
    
    1. IE 对命名空间的支持
      setProperty(),这个方法接 收两个参数:要设置的属性名和属性值
    xmldom.setProperty("SelectionNamespaces", "xmlns:wrox=’http://www.wrox.com/’");
    var result = xmldom.documentElement.selectNodes("wrox:book/wrox:author");
    alert(result.length);
    

    (3) 跨浏览器使用XPath

    1. 重新创建selectSingleNode(),它接收三个参数:上下文节点、XPath 表达式和可选的命名空间对象。
      命名空间对象应该是下面这种字面量的形式:
    {
            prefix1: "uri1",
            prefix2: "uri2",
            prefix3: "uri3"
    }
    
    function selectSingleNode(context, expression, namespaces){
            var doc = (context.nodeType != 9 ? context.ownerDocument : context);
            if (typeof doc.evaluate != "undefined"){
                var nsresolver = null;
                if (namespaces instanceof Object){
                    nsresolver = function(prefix){
                        return namespaces[prefix];
                    }; 
                }
              var result = doc.evaluate(expression, context, nsresolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
              return (result !== null ? result.singleNodeValue : null);
            } else if (typeof context.selectSingleNode != "undefined"){
            //创建命名空间字符串
              if (namespaces instanceof Object){
                    var ns = "";
                    for (var prefix in namespaces){
                        if (namespaces.hasOwnProperty(prefix)){
                            ns += "xmlns:" + prefix + "='" + namespaces[prefix] + "' ";
                         } 
                   }
                   doc.setProperty("SelectionNamespaces", ns);
                }
                return context.selectSingleNode(expression);
            } else {
              throw new Error("No XPath engine found.");
          }
    }
    
    
    var result = selectSingleNode(xmldom.documentElement, "wrox:book/wrox:author", { wrox: "http://www.wrox.com/" });
    alert(serializeXml(result));
    
    1. 重新创建selectNodes()函数。这个函数接收与 selectSingle- Node()相同的三个参数。
    function selectSingleNode(context, expression, namespaces){
            var doc = (context.nodeType != 9 ? context.ownerDocument : context);
            if (typeof doc.evaluate != "undefined"){
                var nsresolver = null;
                if (namespaces instanceof Object){
                    nsresolver = function(prefix){
                        return namespaces[prefix];
                    }; 
                }
             var result = doc.evaluate(expression, context, nsresolver,                                 XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
            var nodes = new Array();
            if (result !== null){
                    for (var i=0, len=result.snapshotLength; i < len; i++)     {
                        nodes.push(result.snapshotItem(i));
                    }
                }
            return nodes;
            } else if (typeof context.selectSingleNode != "undefined"){
            //创建命名空间字符串
              if (namespaces instanceof Object){
                    var ns = "";
                    for (var prefix in namespaces){
                        if (namespaces.hasOwnProperty(prefix)){
                            ns += "xmlns:" + prefix + "='" + namespaces[prefix] + "' ";
                         } 
                   }
                   doc.setProperty("SelectionNamespaces", ns);
                }
               var result = context.selectNodes(expression);
               var nodes = new Array();
               for (var i=0,len=result.length; i < len; i++){
                nodes.push(result[i]);
              }
              return nodes;
            } else {
              throw new Error("No XPath engine found.");
          }
    }
    
    var result = selectNodes(xmldom.documentElement, "wrox:book/wrox:author", { wrox: "http://www.wrox.com/" });
    alert(result.length);
    
    

    3. 浏览器对 XSLT 的支持

    (1) IE中的XSLT

    *简单的 XSLT 转换

    使用 XSLT 样式表转换 XML 文档,将它们分别加到一个 DOM 文档中,然后再使用transformNode()方法这个方法存在于文档的所有节点中,它接受一个参数,即包含 XSLT 样
    式表的文档。调用 transformNode()方法会返回一个包含转换信息的字符串。
    XSLT 转换可以在文档的任何级别上进行。

    //加载 XML 和 XSLT(仅限于 IE)
    xmldom.load("employees.xml");
    xsltdom.load("employees.xslt");
    //转换
    var result = xmldom.transformNode(xsltdom);
    result = xmldom.documentElement.childNodes[1].transformNode(xsltdom);
    result = xmldom.getElementsByTagName("name")[0].transformNode(xsltdom);
     result = xmldom.documentElement.firstChild.lastChild.transformNode(xsltdom);
    
    *复杂的 XSLT 转换
    使用 XSL 模板XSL 处理器
    1. 第一步是要把 XSLT 样式表加载到一个线程安全的 XML 文档中。而这可以通过使用 ActiveX 对象 MSXML2.FreeThreadedDOMDocument 来做到。
    function createThreadSafeDocument(){
        if (typeof arguments.callee.activeXString != "string"){
            var versions = ["MSXML2.FreeThreadedDOMDocument.6.0","MSXML2.FreeThreadedDOMDocument.3.0","MSXML2.FreeThreadedDOMDocument"],i, len;
            for (i=0,len=versions.length; i < len; i++){
                try {
                    new ActiveXObject(versions[i]);
                    arguments.callee.activeXString = versions[i];
                    break;
                } catch (ex){
                    //跳过
                }
              }
         }
        return new ActiveXObject(arguments.callee.activeXString);
    }
    xsltdom.createThreadSafeDocument()
    xsltdom.async = false;
    xsltdom.load("employees.xslt");
    
    1. 在创建并加载了自由线程的 DOM 文档之后,必须将它指定给一个 XSL 模板,这也是一个 ActiveX 对象。而这个模板是用来创建 XSL 处理器对象的。
    function createXSLTemplate(){
        if (typeof arguments.callee.activeXString != "string"){
            var versions = ["MSXML2.XSLTemplate.6.0",
                            "MSXML2.XSLTemplate.3.0",
                            "MSXML2.XSLTemplate"],
    i, len;
            for (i=0,len=versions.length; i < len; i++){
                try {
                    new ActiveXObject(versions[i]);
                    arguments.callee.activeXString = versions[i];
                    break;
                } catch (ex){ 
                    //跳过
                 }
            }
        }
        return new ActiveXObject(arguments.callee.activeXString);
    }
    
    1. 在创建了 XSL 处理器之后,必须将要转换的节点指定给 input 属性。这个值可以是一个文档,也 可以是文档中的任何节点。然后,调用 transform()方法即可执行转换并将结果作为字符串保存在 output 属性中。
    var template = createXSLTemplate();
    template.stylesheet = xsltdom;
    var processor = template.createProcessor();
    processor.input = xmldom;
    processor.transform();
    var result = processor.output;
    

    (2) XSLTProcessor类型

    通过 XSLTProcessor 类型使用 XSLT 转换 XML 文档。

    1. 第一步也是加载两个 DOM 文档,一个基于 XML,另一个基于 XSLT。
    2. 然后, 创建一个新 XSLTProcessor 对象,并使用 importStylesheet()方法为其指定一个 XSLT
    var processor = new XSLTProcessor()
    processor.importStylesheet(xsltdom);
    
    1. 最后一步就是执行转换。
      (1) 调用 transformToDocument()返回一个完整的 DOM 文档。
      (2)调用 transformToFragment()则可以得到一个文档片段对象。
    • 在使用 transformToDocument()时,只要传入 XML DOM,就可以将结果作为一个完全不同的 DOM 文档来使用。
    var result = processor.transformToDocument(xmldom);
    alert(serializeXml(result));
    
    • transformToFragment()方法接收两个参数:要转换的 XML DOM 和应该拥有结果片段的文 档。
    var fragment = processor.transformToDocument(xmldom, document); var div = document.getElementById("divResult"); div.appendChild(fragment);
    

    相关文章

      网友评论

        本文标题:JavaScript 高级程序设计(第18章 JavaScrip

        本文链接:https://www.haomeiwen.com/subject/xiyciftx.html