• javascript和XML


    一,浏览器对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);
  • 相关阅读:
    数据库隔离级别
    前端传递的参数名称和后端接收的参数名称不一致
    事务管理
    AOP
    spring 集成 shiro安全框架
    SpringMVC----@RequestMapping__请求方式
    SpringMVC----@RequestMapping__修饰类
    SpringMVC入门概述+案例
    SpringMVC-web.xml头代码
    Spring注解驱动开发----->容器day02
  • 原文地址:https://www.cnblogs.com/b0xiaoli/p/3659627.html
Copyright © 2020-2023  润新知