一,浏览器对XML DOM的支持
1,DOM2级核心
  var xmldom = document.implementation.createDocument("","root",null);(命名空间,元素标签,文档类型)
  var child = xmldom.createElement("child");
  xmldom.documentElement.appendChild(child);
  检测浏览器支持情况
  var hasXmlDom = document.implementation.hasFeature("XML","2.0")
2,DOMParser类型
  解析XML之前,创建一个DOMParser类型,调用parserFormString(要解析的XML字符串,内容类型text/xml)方法
  解析发生错误时,parseFromString()返回一个document对象,这个对象的文档元素是<parsererror>

var parser = new DOMParser(),xmldom,errors;
try{
  xmldom = parser.parseFormString("<root>","text/xml");
  errors = xmldom.getElementsByTagName("parsererror");
  if(errors.length > 0){
    throw new Error("Parsing errot!");
  }
}catch(ex){
  alert("Parsing error!");
}

3,XMLSerializer类型
  XMLSerializer类型,将DOM文档序列化为XML字符串
  首先创建一个XMLSerializer实例,然后将文档传人其serializerToString()方法
  var serializer = new XMLSerializer();
  var xml = serializer.serializerToString(xmldom);
4,IE8及之前版本中的XML、
  IE是第一个支持XML的浏览器,通过ActiveX对象实现
  为了便于桌面应用程序开发人员处理XML,微软创建了MSXML库
  ActiveXObject类型,可以通过它创建ActiveX对象的实例,要创建一个XML文档的类型,要使用ActiveXObject构造函数,传人一个表示XML文档版本的字符串
  有六种不同的XML文档版本可以供选择
    Microsoft.XmlDom:最初随同IE发布,不建议使用
    MSXML2.DOMDocument:为方便脚本处理更新的版本,建议在特殊情况下作为后备版本
    MSXML2.DOMDocument.3.0:在Javascript中使用,是最低的建议版本
    MSXML2.DOMDocument.4.0:通过脚本处理时不可靠,可能导致安全警告
    MSXML2.DOMDocument.5.0:通过脚本处理时不可靠,可能导致安全警告
    MSXML2.DOMDocument.6.0:通过脚本能够可靠处理的最新版本

    function createDocument(){
      if(typeof argument.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]);
            argument.callee.activeXString = versions[i];
          }catch(ex){
            //跳过
          }
        }
      }  
      return new ActiveXObject(argument.callee.activeXString);
  }  

  要解析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的值
  在调用loadXML()之后,查询XML文档之前,检测是否发生了错误
1,序列化XML
  每个DOM节点都有一个xml属性,保存着表示该节点的XML字符串
2,加载XML文件
  IE中的XML文档对象也可以加载来自服务器的文件,指定加载文档的方式,asyns属性,true表示异步加载,false表示同步加载
  var xmldom = createDocument();
  xmldom.async = false;
  加载了XML文档之后,调用load()可以启动下载过程,接收一个参数即要加载的XML文件的URL,同步方式下,调用load后立即检测解析错误并执行相关XML处理
  var xmldoe = createDocument();
  xmldom.async = false;
  xmldom.load("example.xml");
  if(xmldom.parseError != 0){
    //处理错误
  }else{
    //处理xml外部文档
  }
  异步加载XML文件情况下,为XML DOM文档的onreadystatechange事件指定处理程序,4个就绪状态
    1,DOM正在加载数据,2DOM已经加载完数据,3DOM可以使用,但某些部分还无法访问,4DOM完全可以使用

  var xmldom = createDocument();
  xmldom.asyns = true;
  xmldom.onreadystatechange = function(){
    if(xmldom.readyState == 4){
      if(xmldom.parseError != 0 ){
        //处理xmldom文档中错误
      }else{
        //处理xmldom文档
      }
    }  
  };
  xmldom.onload("example.xml");

5,跨浏览器处理XML
  解析XML而言

  function parseXml(xml){
    var xmldom = null;
    if(typeof DOMParser != "undefined"){
      xmldom = (new DOMParser()).parseFormString(xml,"text/xml");
      var errors = xmldom.getElementsByTagName("parsererror");
      if(errors.length){
        throw new Error("XML parseing 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.");
    }
  }

二,浏览器对XPath的支持
1,DOM3级XPath
  XPath是设计用来在DOM文档中查找节点的一种手段
  DOM3定义了在DOM中对XPath表达式求值的接口
  var supportsXPath = document.implementation.hasFeature("XPath","3.0");
  XPathEvaluator类型,用于特定的上下文中对XPath表达式求值,有3个方法
    createExpression(expression,nsresolver)将XPath表达式及相应的命名空间信息转换成一个XPathExpression,多次使用同一个查询时有用
    createNSResolver(node),根据node的命名空间信息创建一个新的XPathNSResolver对象,基于使用命名空间XML文档求值时,需要使用                 XPathNSResolver对象
    evaluate(expression,context,nsresolver,type,result),给定的上下文中,基于特定的命名空间信息对XPath表达式求值,剩下的参数指定如何返回结果
    expression为XPath表达式,contenxt为上下文节点,nsresolver为命名空间求解器只在XML代码中使用了XML命名空间时有必要指定,没有命名空间          时指定为null,type为结果类型取值如下
      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:返回只包含一个节点的节点集合,包含的这个节点就是文档中第一个匹配的节点

  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();
    }
  }

  返回结果为XPathResult.ORDERED_NODE_ITERATOR_TYPE,是常用的返回类型,没有节点匹配XPath表达式,返回null,否则返回XPathResult对象
  返回的XPathResult对象带有属性和方法,如果节点时节点迭代器与次序无关,要使用iterateNext()从节点中取得匹配的节点,没有更多的匹配节点时,返回null
  如果指定的快照结果类型,使用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);
    }
  }
  1)单节点结果
  指定常量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.singliNodeValue.tagName);
  }
  2)简单类型结果
  通过XPathResult的布尔值,数值,和字符串值可以取得简单的非节点的数据类型
  对于XPathResult.BOOLEAN_TYPE,有返回值为true,无返回值为false
  对于XPathResult.NUMBER_TYPE,必须在XPath表达式参数的位置上指定一个能够返回数值的XPath函数,没有匹配返回NaN
    var Result = xmldom.evaluate("count(employee/name)",xmldom.documentElement,null,XPathResult.NUMBER_TYPE,null);
  对于字符串类型,查找与XPath表达式匹配的第一个节点,返回第一个子节点的值,没有匹配返回空字符串
  3)默认类型结果
  使用XPathResult.ANY_TYPE会自动返回结果的类型,确定返回的是什么结果,通过检测resultType属性
  4)命名空间支持
  对于利用了命名空间的XML,XPathEvaluator必须知道命名空间的信息
  处理命名空间的一种方法是通过createNSResolver()创建XPathNSResolver对象,接收一个参数就是包含命名空间定义的节点,传人到evaluate方法中
  处理命名空间的另一种方法是定义一个函数,让它接收一个命名空间前缀,返回关联的URL
  var nsresolver = function(prefix){
    switch(prefix){
      case "wrox":return "http://www.wrox.com/"
    }
  };
  传人evaluate方法中
2,IE中的XPath
  IE对XPath的支持是内置在基于ActiveX的XMLDOM文档对象中的,没有使用DOMParser返回的DOM对象
  使用XPath必须基于ActiveX的实现,这个接口在每个节点上额外定义了两个方法
  selectSingleNode(),接受一个XPath模式,在找到匹配节点时返回第一个匹配的节点,没有匹配返回null
  selectNodes(),接受一个XPath模式,返回与模式匹配的所有节点的NodeList,没有匹配,返回包含零项的NodeList
  IE中处理包含命名空间的XPath表达式,必须知道自己使用的命名空间,按照下列格式创建一个字符串
    "xmlns:prefix1='uri1' xmlns='uri2' xmlns='uri3'"
  将这个字符串传人到XMLDOM文档对象的特殊方法setProperty(属性名,属性值)中,属性名为SelectionNamespaces,属性值就是按照前面格式创建的字符串
    xmldom.setProperty("SelectionNamespaces","xmlns:wrox='http://www.wrox.com/'");
    var result = xmldom.documentElement.selectNodes("wrox:book/www:author");
3,跨浏览器使用XPath
  selectSingleNode(上下文节点,XPath表达式,命名空间对象)

  function selectSingNode(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.hasOwnerProperty(prefix)){
            ns += "xmlns:" + prefix + "= '" + namespaces[prefix] + "' ";
          }
        }
        doc.serProperty("SelectionNamespaces",ns);
      }
      return context.selectSingleNode(expression);
    }else{
      throw new Error("No XPath engine found.");
    }
  }

  selectNodes()函数,

  function selectNodes(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.selectNodes != "undefined"){
      if(namespaces instanceof Object){
        var ns = "";
        for(var prefix in namespace){
          if(namespace.hasOwnProperty(prefix)){
            ns += "xmlns:" + prefix + "=' + namespaces[prefix] + '" ";
          }
        }
        doc.serProperty("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.");
    }
  }

三,浏览器对XSLT的支持
1,IE中的XSLT
  1)简单的XSLT转换
  使用XSLT样式表转化XML文档的最简单的方法,是将他们分别放在一个DOM文档中,然后使用transformNode()方法
  这个方法存在于所有节点中,接收一个参数,包含XSLT样式表的文档,返回一个包含转换信息的字符串
  xmldom.load("employees.xml");
  xsltdom.load("employees.xslt");
  var result = xmldom.transformNode(xsltdom);
  可以在文档的任何级别上进行转换
  2)复杂的XSLT转换
  使用XSL模板和XML处理器,第一步是把XSLT样式表加载到一个线程安全的XML文档中,通过使用ActiveX对象MSXML2.FreeThreadedDOMDocument来做
  创建线程安全的XML DOM,即ActiveX对象,与常规的DOM支持相同的接口

  function createThreadSafeDocument(){
    if(typeof argument.callee.activeXString != "string"){
      var verions = ["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]);
          argument.callee.activeXString = versions[i];
          break;
        }catch(ex){
          //跳过
        }
      }
    }
    return new ActiveXObject(arguments.callee.activeXString);
  }
  var xsltdom = createThreadSafeDocument();
  xsltdom.async = false;
  xsltdom.load("employee.xslt");

  创建并加载了自由线程的DOM之后,必须将它指定给一个XSL模板,这也是一个ActiveX对象,这个模板用来创建XSL处理对象的,后者用来转换XML文档

  function createXSLTemplate(){
    if(typeof argument.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]);
          argument.callee.activeXString = version[i];
          break;
        }catch(ex){
        //跳过
        }
      }
    }
    return new ActiveXObject(arguments.callee.activeXString);
  }
  var template = createXSLTemplate();
  template.stylesheet = xsltdom;
  var proccessor = template.createProcessor();
  processor.input = xmldom;
  processor.transform();
  var result = processor.output;

  transform方法可执行转换并将结果作为字符串保存在output属性中
  XSLT样式表可以接受传人的参数,并将其用作局部变量
  processor.input = xmldom.documentElement;
  processor.addParameter("message","hello");
  processor.transform();
  XSL处理器能够设置一种操作模式,可是使用mode特性为模板定义一种模式,
  processor.input = xmldom;
  processor.addParameter("message","hellp");
  processor.setStartMode("title-first");
  processor.transform();
  如果打算使用同一样式表进行多次转换,可以在转换之后重置处理器,调用reset()方法
  会清除原先的输入和输出属性,启动模式以及其他指定的参数,
2,XSLTProcessor类型
  可以通过XSLTProcessor类型,使用XSLT转换XML文档
  与IE类似,第一步加载两个DOM文档,一个基于XML,一个基于XSLT,然后创建XSLTProcessor对象,
  指定importStyleSheet()方法为其指定一个XSLT,
  var processor = new XSLTProcessor();
  processpr.importStyleSheet(xsltdom);
  最后一步执行转换,想返回完整的DOM文档,使用transformToDocument(),想返回一个文档对象片段,使用transformToFragment(),将返回的结果添加     到另一个DOM文档中
  XSLT样式表在输出格式为XML或HTML时,没有问题,当格式为text时,浏览器支持情况不同,这时使用transformToFragment()
  var fragment = processpr.transformToFragment(xmldom,document);
  var text = fragment.firstChild.nodeValue;
  alert(text);
  1)使用参数
  XSLTProcessor类型通过serParameter()设置XSLT的参数,命名空间URL,参数内部名称,要设置的值
  要在调用transformToDocument(),transformToFragment()之前调用
  var processor = new XSLTProcessor();
  processor.importStyleSheet(xsltdom);
  processor.setParameter(null,"message",null);
  var result = processor.transformToDocument(xmldom);
  getParameter()取得当前参数的值,(命名空间(一般为null),参数的名称)
  removeParameter()移除当前参数的值(命名空间(一般为null),参数的名称)
  2)重置处理器
  processor.reset()
  移除所有参数和样式,可以再次调用importStyleSheet()
3,跨浏览器使用XSLT

  function transform(context,xslt){
    if(typeof XSLTProcessor != "undefined"){
      var processor = new XSLTProcessor();
      processor.importStylesheet(xslt);
      var result = processor.transformToDocument(context);
      return (new XMLSerializer()).serializeToString(result);
    }else if(typeof context.transformNode != "undefined"){
      return context.transformNode(xslt);
    }else{
      throw new Error("No XSLT processor available");
    }
  }
  var result = transform(xmldom,xsltdom);

javascript和XML的更多相关文章

  1. ajax-异步JavaScript和XML

    什么是ajax? ajax是异步的javascript和XML ( Asynchronous Javascript And XML ) 优点:节省用户操作时间,提高用户体验.减少数据请求次数. 什么是 ...

  2. JavaScript操作XML

    JavaScript操作XML (一) JavaScript操作XML是通过XML DOM来完成的.那么什么是XML DOM呢?XML DOM 是: 用于 XML 的标准对象模型 用于 XML 的标准 ...

  3. 18. javacript高级程序设计-JavaScript与XML

    1. JavaScript与XML IE采取了下列方式: l 通过ActiveX对象来支持处理XML,而相同的对象也可以用来构建桌面应用程序 l Windows携带了MSXML库,JavaScript ...

  4. JavaScript实现XML与JSON互转代码(转载)

    下面来分享一个关于JavaScript实现XML与JSON互转例子,这里面介绍了国外的三款xml转json的例子,希望这些例子能给你带来帮助. 最近在开发在线XML编辑器,打算使用JSON做为中间格式 ...

  5. 用javascript操作xml

    用javascript操作xml 可以使用标准DOM操作. IE创建XML MSXML2.0DOMDocument function createXMLDOM(){ var version = [ ' ...

  6. 第一百二十五节,JavaScript,XML

    JavaScript,XML 学习要点: 1.IE中的XML 2.DOM2中的XML 3.跨浏览器处理XML 随着互联网的发展,Web应用程序的丰富,开发人员越来越希望能够使用客户端来操作XML技术. ...

  7. javascript与XML

    曾几何时,XML一度成为存储和通过因特网传输结构化数据的标准,之前,浏览器无法解析XML数据时,开发人员都要手动编写自己的XML解析器.而自从DOM出现后,所有浏览器都内置了对XML的原生支持(XML ...

  8. C#将XML转换成JSON 使用 JavaScript 将 XML 转成 JSON

    如何在ASP.NET中用C#将XML转换成JSON [JavaScript]代码 // Changes XML to JSON function xmlToJson(xml) { // Create ...

  9. javascript读取xml文件读取节点数据的例子

    分享下用javascript读取xml文件读取节点数据方法. 读取的节点数据,还有一种情况是读取节点属性数据. <head> <title></title> < ...

  10. How to make an HTTP request 异步 JavaScript 和 XML

    https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started In order to make an HTTP request to th ...

随机推荐

  1. Py-多态,封装,反射,描述符,包装标准类型,面向对象进阶

    多态: 对象可以通过他们共同的属性和动作来访问,而不需要考虑他们的类多态是继承的应用 class H2o: def __init__(self,temp): self.temp=temp def ht ...

  2. JVM有哪些垃圾回收器

    JVM 的垃圾回收器 目录 JVM 的垃圾回收器 经典垃圾收集器 Serial 收集器 ParNew 收集器 Parallel Scavenge 收集器 Serial Old 收集器 Parallel ...

  3. 【Android初级】如何实现一个“模拟后台下载”的加载效果(附源码)

    在Android里面,后台的任务下载功能是非常常用的,比如在APP Store里面下载应用,下载应用时,需要跟用户进行交互,告诉用户当前正在下载以及下载完成等. 今天我将通过使用Android的原生控 ...

  4. 前端面试之JavaScript中的闭包!

    前端面试之JavaScript中的闭包! 闭包 闭包( closure )指有权访问另一个函数作用域中变量的函数. ----- JavaScript 高级程序设计 闭包其实可以理解为是一个函数 简单理 ...

  5. Avoid catching exceptions inside atomic! You may need to manually revert model state when rolling back a transaction. 避免异常程序不抛错误 回滚 导致 自增id不连续。

    https://docs.djangoproject.com/en/3.0/topics/db/transactions/ You may need to manually revert model ...

  6. C# 防止程序多开(重复开启)

    Mutex(mutual exclusion,互斥)是 .Net Framework 中提供跨多个线程同步访问的一个类.它非常类似了 Monitor 类,因为他们都只有一个线程能拥有锁定.而操作系统能 ...

  7. (数据科学学习手札105)Python+Dash快速web应用开发——回调交互篇(中)

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...

  8. 通过 JFR 与日志深入探索 JVM - TLAB 原理详解

    全系列目录:通过 JFR 与日志深入探索 JVM - 总览篇 什么是 TLAB? TLAB(Thread Local Allocation Buffer)线程本地分配缓存区,这是一个线程专用的内存分配 ...

  9. 透明小电视上线——GitHub 热点速览 v.21.05

    作者:HelloGitHub-小鱼干 这周的 GitHub Trending 真是棒极了.小鱼干喜欢的科技博主又开源了他的硬件玩具,一个透明的小电视机,HG 的小伙伴看完项目,再买个电路板和分光棱镜, ...

  10. Linux环境mysql快速备份及迁移

    在项目实施的过程中,经常会面临数据库迁移,导出和导出数据,如果用普通的mysql客户端备份,时间较长且容易出错.那么mysql快速备份及迁移,就成为数据库迁移的重中之重. 下面介绍我在项目实现过程中用 ...