【问题标题】:XML parsing of a variable string in JavaScriptJavaScript中变量字符串的XML解析
【发布时间】:2010-10-13 13:43:59
【问题描述】:

我有一个变量字符串,其中包含格式正确且有效的 XML。我需要使用 JavaScript 代码来解析这个提要。

如何使用(与浏览器兼容的)JavaScript 代码完成此操作?

【问题讨论】:

    标签: javascript xml parsing


    【解决方案1】:

    2017 年更新答案

    以下将在所有主流浏览器中将 XML 字符串解析为 XML 文档。除非您需要支持 IE

    function parseXml(xmlStr) {
       return new window.DOMParser().parseFromString(xmlStr, "text/xml");
    }
    

    如果你需要支持 IE

    var parseXml;
    
    if (typeof window.DOMParser != "undefined") {
        parseXml = function(xmlStr) {
            return new window.DOMParser().parseFromString(xmlStr, "text/xml");
        };
    } else if (typeof window.ActiveXObject != "undefined" &&
           new window.ActiveXObject("Microsoft.XMLDOM")) {
        parseXml = function(xmlStr) {
            var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async = "false";
            xmlDoc.loadXML(xmlStr);
            return xmlDoc;
        };
    } else {
        throw new Error("No XML parser found");
    }
    

    通过parseXml 获得Document 后,您可以使用常用的DOM 遍历方法/属性,例如childNodesgetElementsByTagName() 来获取您想要的节点。

    示例用法:

    var xml = parseXml("<foo>Stuff</foo>");
    alert(xml.documentElement.nodeName);
    

    如果您使用的是 jQuery,从 1.5 版本开始,您可以使用其内置的 parseXML() 方法,其功能与上述功能相同。

    var xml = $.parseXML("<foo>Stuff</foo>");
    alert(xml.documentElement.nodeName);
    

    【讨论】:

    • 我同意,这应该被接受。我的回答从早期开始就太老了,我总是觉得它仍然会得到支持。有人赞成删除我接受的答案吗?投票系统有缺陷吗?为这些人点赞!
    • @SanderVersluys:你能删除你的答案吗?
    • 不得不反对你说“没有其他像样的答案”。 @SanderVersluys 的回答对我来说效果很好。这有什么不好的,我不知道。
    • @EricTurner:我坚持这一点,桑德本人否认了他的回答。 jQuery docs tell you not to use $() for XML parsing。仔细阅读 cmets:它在许多情况下根本不起作用。
    • @DWoldrich:我在网上看到了两种方式,我怀疑它是双向的。我能找到的最接近权威答案的是msdn.microsoft.com/en-us/library/ms761398(v=vs.85).aspx,它表示应该使用布尔值。但是,您在其中放置多少价值完全取决于您,jQuery's parseXML() method 使用字符串。我对更改答案有点谨慎,因为我现在没有简单的方法来测试它。
    【解决方案2】:

    更新:如需更正确的答案,请参阅 Tim Down's answer

    Internet Explorer 和(例如,基于 Mozilla 的浏览器)为 XML 解析公开了不同的对象,因此使用像 jQuery 这样的 JavaScript 框架来处理跨浏览器的差异是明智的。

    一个非常基本的例子是:

    var xml = "<music><album>Beethoven</album></music>";
    
    var result = $(xml).find("album").text();
    

    注意:正如 cmets 中指出的那样; jQuery 并没有真正进行任何 XML 解析,它依赖于 DOM innerHTML 方法,并且会像解析任何 HTML 一样解析它,因此在 XML 中使用 HTML 元素名称时要小心。但我认为它对于简单的 XML“解析”效果相当好,但它可能不建议用于密集或“动态”XML 解析,在这种情况下你不预先知道什么 XML 会下降,这会测试一切是否按预期解析。

    【讨论】:

    • 用于抽象出 IE 和其他浏览器之间的 XML 解析差异的代码是几行微不足道的代码,因此不值得单独使用 50K 的 jQuery。操作生成的 XML 的 DOM 是另一回事。
    • 在发布我之前的评论时我没有意识到 jQuery 甚至不解析 XML,它只是将其分配为元素的 innerHTML 属性,即一点都不可靠。
    • 请注意,JQuery 不支持 XML 命名空间。见zachleat.com/web/2008/05/10/selecting-xml-with-javascript
    • 这个答案是错误的。请参阅stackoverflow.com/questions/2124924/…stackoverflow.com/questions/2908899/…、@Tim Down 的回答和jQuery documentation itself,其中指出:“请注意 [jQuery()] 解析 HTML,not XML”
    • @SanderVersluys:由于作者不接受另一个答案,我会在您的答案中包含一个注释,链接到@TimDown's 正确答案。这样人们就不必阅读所有这些 cmets 来找出正确的答案。
    【解决方案3】:

    网络上的大多数示例(以及上面介绍的一些示例)展示了如何以与浏览器兼容的方式从文件加载 XML。这很容易,除了不支持document.implementation.createDocument() 方法的谷歌浏览器。使用 Chrome 时,为了将 XML 文件加载到 XmlDocument 对象中,您需要使用内置的 XmlHttp 对象,然后通过传递它的 URI 来加载文件。

    在您的情况下,情况有所不同,因为您希望从字符串变量而不是 URL 加载 XML。然而,对于这个要求,Chrome 应该像 Mozilla 一样工作(或者我听说过)并且支持 parseFromString() 方法。

    这是我使用的一个函数(它是我当前正在构建的浏览器兼容性库的一部分):

    function LoadXMLString(xmlString)
    {
      // ObjectExists checks if the passed parameter is not null.
      // isString (as the name suggests) checks if the type is a valid string.
      if (ObjectExists(xmlString) && isString(xmlString))
      {
        var xDoc;
        // The GetBrowserType function returns a 2-letter code representing
        // ...the type of browser.
        var bType = GetBrowserType();
    
        switch(bType)
        {
          case "ie":
            // This actually calls into a function that returns a DOMDocument 
            // on the basis of the MSXML version installed.
            // Simplified here for illustration.
            xDoc = new ActiveXObject("MSXML2.DOMDocument")
            xDoc.async = false;
            xDoc.loadXML(xmlString);
            break;
          default:
            var dp = new DOMParser();
            xDoc = dp.parseFromString(xmlString, "text/xml");
            break;
        }
        return xDoc;
      }
      else
        return null;
    }
    

    【讨论】:

    • 我知道关于浏览器嗅探的争议性意见,这就是我没有在此处包含该功能的原因。但是,尚未确定它是错误的。无论如何,这是一个暗示性的例子。
    • 我认为这是错误的,因为您不能保证它是正确的。任何人都可以欺骗 UA 字符串,而且每个非 IE 浏览器都支持 DOMParser 以及您的浏览器嗅探是否完美是值得怀疑的。此外,以正确的方式更容易做到这一点:if(window.ActiveXObject){...}
    • 那么现在 IE9+ supports DOMParser,你将如何支持它? -1 表示 @1j01 所说的。您只需检查var dp; try{ dp = new DOMParser() } catch(e) { }; if(dp) { // DOMParser supported } else { // alert('you need to consider upgrading your browser\nOr pay extra money so developer can support the old versions using browser sniffing (eww)') }
    【解决方案4】:

    Marknote 是一个不错的轻量级跨浏览器 JavaScript XML 解析器。它是面向对象的,并且有大量示例,另外还记录了 API。这是相当新的,但到目前为止它在我的一个项目中运行良好。我喜欢它的一件事是它可以直接从字符串或 URL 读取 XML,您还可以使用它将 XML 转换为 JSON。

    以下是您可以使用 Marknote 做什么的示例:

    var str = '<books>' +
              '  <book title="A Tale of Two Cities"/>' +
              '  <book title="1984"/>' +
              '</books>';
    
    var parser = new marknote.Parser();
    var doc = parser.parse(str);
    
    var bookEls = doc.getRootElement().getChildElements();
    
    for (var i=0; i<bookEls.length; i++) {
        var bookEl = bookEls[i];
        // alerts "Element name is 'book' and book title is '...'"
        alert("Element name is '" + bookEl.getName() + 
            "' and book title is '" + 
            bookEl.getAttributeValue("title") + "'"
        );
    }
    

    【讨论】:

    • 看来marknote 实现了一个纯javascript解析器。这意味着它应该与任何 javascript 引擎兼容,无论它用于浏览器、node.js 还是独立的 javascript 引擎......
    • 自 2021 年 6 月起,请注意 Marknote 不再维护。 fast-xml-parser 是一个维护的替代方案。
    【解决方案5】:

    我一直使用以下在 IE 和 Firefox 中有效的方法。

    示例 XML:

    <fruits>
      <fruit name="Apple" colour="Green" />
      <fruit name="Banana" colour="Yellow" />
    </fruits>
    

    JavaScript:

    function getFruits(xml) {
      var fruits = xml.getElementsByTagName("fruits")[0];
      if (fruits) {
        var fruitsNodes = fruits.childNodes;
        if (fruitsNodes) {
          for (var i = 0; i < fruitsNodes.length; i++) {
            var name = fruitsNodes[i].getAttribute("name");
            var colour = fruitsNodes[i].getAttribute("colour");
            alert("Fruit " + name + " is coloured " + colour);
          }
        }
      }
    }
    

    【讨论】:

    • 如果遇到这种情况,你会如何取值value
    • @Siblja 你需要使用innerText 而不是getAttribute()
    【解决方案6】:

    显然 jQuery 现在提供 jQuery.parseXML http://api.jquery.com/jQuery.parseXML/ 从 1.5 版开始

    jQuery.parseXML( data ) 返回:XMLDocument

    【讨论】:

      【解决方案7】:

      请查看XML DOM Parser (W3Schools)。这是一个关于 XML DOM 解析的教程。实际的 DOM 解析器因浏览器而异,但 DOM API 是标准化的并且保持不变(或多或少)。

      如果您可以 restrict 自己到 Firefox,也可以使用 E4X。它相对更容易使用,并且从 1.6 版开始就成为 JavaScript 的一部分。这是一个小示例用法...

      //Using E4X
      var xmlDoc=new XML();
      xmlDoc.load("note.xml");
      document.write(xmlDoc.body); //Note: 'body' is actually a tag in note.xml,
      //but it can be accessed as if it were a regular property of xmlDoc.
      

      【讨论】:

        【解决方案8】:

        免责声明:我创建了fast-xml-parser

        我创建了fast-xml-parser 来将XML 字符串 解析为JS/JSON 对象或中间遍历对象。预计它将在所有浏览器中兼容(但仅在 Chrome、Firefox 和 IE 上进行了测试)。

        用法

        var options = { //default
            attrPrefix : "@_",
            attrNodeName: false,
            textNodeName : "#text",
            ignoreNonTextNodeAttr : true,
            ignoreTextNodeAttr : true,
            ignoreNameSpace : true,
            ignoreRootElement : false,
            textNodeConversion : true,
            textAttrConversion : false,
            arrayMode : false
        };
        
        if(parser.validate(xmlData)){//optional
            var jsonObj = parser.parse(xmlData, options);
        }
        
        //Intermediate obj
        var tObj = parser.getTraversalObj(xmlData,options);
        :
        var jsonObj = parser.convertToJson(tObj);
        

        注意:它不使用 DOM 解析器,而是使用 RE 解析字符串并将其转换为 JS/JSON 对象。

        Try it online, CDN

        【讨论】:

          【解决方案9】:
          <script language="JavaScript">
          function importXML()
          {
              if (document.implementation && document.implementation.createDocument)
              {
                      xmlDoc = document.implementation.createDocument("", "", null);
                      xmlDoc.onload = createTable;
              }
              else if (window.ActiveXObject)
              {
                      xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
                      xmlDoc.onreadystatechange = function () {
                              if (xmlDoc.readyState == 4) createTable()
                      };
              }
              else
              {
                      alert('Your browser can\'t handle this script');
                      return;
              }
              xmlDoc.load("emperors.xml");
          }
          
          function createTable()
          {
              var theData="";
              var x = xmlDoc.getElementsByTagName('emperor');
              var newEl = document.createElement('TABLE');
              newEl.setAttribute('cellPadding',3);
              newEl.setAttribute('cellSpacing',0);
              newEl.setAttribute('border',1);
              var tmp = document.createElement('TBODY');
              newEl.appendChild(tmp);
              var row = document.createElement('TR');
              for (j=0;j<x[0].childNodes.length;j++)
              {
                      if (x[0].childNodes[j].nodeType != 1) continue;
                      var container = document.createElement('TH');
                      theData = document.createTextNode(x[0].childNodes[j].nodeName);
                      container.appendChild(theData);
                      row.appendChild(container);
              }
              tmp.appendChild(row);
              for (i=0;i<x.length;i++)
              {
                      var row = document.createElement('TR');
                      for (j=0;j<x[i].childNodes.length;j++)
                      {
                              if (x[i].childNodes[j].nodeType != 1) continue;
                              var container = document.createElement('TD');
                              var theData = document.createTextNode(x[i].childNodes[j].firstChild.nodeValue);
                              container.appendChild(theData);
                              row.appendChild(container);
                      }
                      tmp.appendChild(row);
              }
              document.getElementById('writeroot').appendChild(newEl);
          }
          </script>
          </HEAD>
          
          <BODY onLoad="javascript:importXML();">
          <p id=writeroot> </p>
          </BODY>
          

          更多信息请参考http://www.easycodingclub.com/xml-parser-in-javascript/javascript-tutorials/

          【讨论】:

            【解决方案10】:

            也可以通过jquery函数($.parseXML)来操作xml字符串

            示例 javascript:

            var xmlString = '<languages><language name="c"></language><language name="php"></language></languages>';
            var xmlDoc = $.parseXML(xmlString);
            $(xmlDoc).find('name').each(function(){
                console.log('name:'+$(this).attr('name'))
            })
            

            【讨论】:

              猜你喜欢
              • 2017-11-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-05-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多