zoukankan      html  css  js  c++  java
  • 判断是否XML文档

    xhtml的昙花一现带来不少问题,它的目的是让html表现得更像xml,所以才叫xhtml。但是出师未捷身先死,我们讨论一下如何判定文档是XML吧。

    印象中jQuery对此方法重复实现了许多次,应该比较权威,也说明这判定比较难搞。看jQuery1.42的实现:

         var isXML = function(elem){
                // documentElement is verified for cases where it doesn't yet exist
                // (such as loading iframes in IE - #4833)
                var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
                return documentElement ? documentElement.nodeName !== "HTML" : false;
            };
    

    好,做一个实验:

      window.onload = function(){
            try{
              var doc = document.implementation.createDocument(null, 'HTML', null);//只限标准浏览器,创建一个XML文档
              alert(doc.documentElement)
              alert(isXML(doc))//应该返回true
            }catch(e){
              alert("不支持creatDocument方法")
            }
        }
    

    另一个实验:

    评测结果,它能判定XHTML文档,但无法判定第一个元素为HTML的XML文档。

    看来我们需要一些更可靠的特征侦探。我们知道IE的HTML不支持xpath,而XML支持,这个可以利用。对于标准浏览器,参见我另一篇博文《javascript 跨文档调用技术》提到的一系列方法。既然有createHTMLDocument,应该拥有HTMLDocument这个对象,标准浏览器向来比较慷慨,暴露了许多比较底层的方法供我们扩展,如__proto__, Node,Window, Element, HTMLElement什么的。测试一下,真的有这东西

    在火狐官网还看到这样一个判定,这是基于XUL的,仅对火狐有效。

    //https://developer.mozilla.org/En/XML/Identifying_XML_elements_and_documents
    function isXMLDoc (doc) { 
        var Ci = Components.interfaces;
        // Remove the second condition if only wish to test for XML, not XUL
        return (doc instanceof Ci.nsIDOMXMLDocument)||
               (doc instanceof Ci.nsIDOMXULDocument);
    }
    

    不管怎么样,既然获知HTMLDocument这个类,就简单了。下面是我的实现:

          var isXML = (function(){
            if(-[1,]){
              return function(doc){
                return  !(doc instanceof HTMLDocument)
              }
            }else{
              return function(doc){
                return "selectNodes" in doc
              }
            }
          })();
    

    下面是测试代码:

          var createXML = function (str) {
            if (typeof DOMParser !== "undefined") {
              return (new DOMParser()).parseFromString(str, "application/xml");
            }else if (ActiveXObject) {
              var xml = new ActiveXObject("Microsoft.XMLDOM");
              xml.async="false";
              xml.loadXML(str);
              return xml
            }
          }
    
          window.onload = function(){
            var xml = createXML('<HTML><body><book><title>司徒正美</title></book></body></HTML>');   
            alert(isXML(xml))
          }
    

    可能有人会问,为什么不用XMLDocumet?好问题,因为XMLDocumet在opera中支持得比较晚。大抵是opera9.6才支持,这是我以前在日本博客看到的数据。不过opera是个小众的浏览器,你大可以不管它比较旧的版本,而直接用XMLDocument。

    补充一下,我以前是使用以下判定的,一样可行,但是要创建两个元素对象。在IE7中,没有加入DOM树的元素节点不会被回收,需要特殊处理一下,比较麻烦,遂放弃之。

       var isXML =  function (doc) {
            return doc.createElement("p").nodeName !== doc.createElement("P").nodeName;
          };
    
           // Safari 2 missing document.compatMode property
      // makes harder to detect Quirks vs. Strict mode
      var isQuirks =
        function(document) {
          return (document.compatMode ?
            (document.compatMode.indexOf('CSS') < 0) :
            (function() {
              var div = document.createElement('div'),
                isStrict = div.style &&
                  (div.style.width = 1) &&
                  div.style.width != '1px';
              div = null;
              return !isStrict;
            })());
        },
    
      // XML is functional in W3C browsers
      isXML = 'xmlVersion' in doc ?
        function(document) {
          return !!document.xmlVersion ||
            (/xml$/).test(document.contentType) ||
            !(/html/i).test(document.documentElement.nodeName);
        } :
        function(document) {
          return document.firstChild.nodeType == 7 &&
            (/xml/i).test(document.firstChild.nodeName) ||
            !(/html/i).test(document.documentElement.nodeName);
        };
    
      // reset and reused dynamically for each selection
      isQuirksMode = isQuirks(doc),
    
      // reset and reused dynamically for each selection
      isXMLDocument = isXML(doc),
    
        function isXML(context) {
              context = context.ownerDocument || document;
              return context.createElement("p").nodeName !== context.createElement("P").nodeName
            }
    
  • 相关阅读:
    Cefsharp 75 设置代理
    C# Winform 执行JS脚本
    Cefsharp 75 为每个实例单独设置缓存目录
    QQ邮箱发送邮件,出现mail from address must be same as authorization user错误
    软件卸载后自动重装,服务器中了流氓软件解决方法
    win版宝塔更新后,宝塔无法启动(修复办法)
    C的typedef
    为Arch Linux安装桌面
    在Simplicity Studio下创建适用于EFR32的工程项目
    在VMWare上安装Arch Linux
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1685360.html
Copyright © 2011-2022 走看看