JavaScript 中变量字符串的 XML 解析

IT技术 javascript xml parsing
2021-02-08 03:31:54

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

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

6个回答

2017 年更新的答案

下面将在所有主流浏览器中将 XML 字符串解析为 XML 文档。除非您需要支持 IE <= 8 或一些晦涩的浏览器,否则您可以使用以下功能:

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

如果您需要支持 IE <= 8,以下将完成这项工作:

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

一旦你有一个Document通过获得的parseXml,你可以使用通常的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 的回答在我的情况下效果很好。这有什么不体面的,我不知道。
2021-03-15 03:31:54
我同意,这应该是被接受的答案。我的答案从一开始就很老了,我总是觉得很好奇它仍然得到了赞成。有人赞成删除我接受的答案吗?投票系统有缺陷吗?为这些人点赞!
2021-03-21 03:31:54
@SanderVersluys:你能删除你的答案吗?
2021-03-21 03:31:54
@EricTurner:我支持它,而桑德本人否认了他的回答。jQuery 文档告诉您不要$()用于 XML 解析更仔细地阅读评论:它在许多情况下根本不起作用。
2021-04-05 03:31:54
@DWoldrich:我在网上看到了两种方式,我怀疑它是双向的。我能找到的最接近权威答案的是msdn.microsoft.com/en-us/library/ms761398(v=vs.85).aspx,它说应该使用布尔值。但是,您在其中放置多少value完全取决于您,jQuery 的parseXML()方法使用字符串。我对改变答案有点谨慎,因为我现在没有简单的方法来测试它。
2021-04-06 03:31:54

更新:有关更正确的答案,请参阅Tim Down 的答案

Internet Explorer 和例如基于 Mozilla 的浏览器公开不同的对象以进行 XML 解析,因此使用jQuery 之类的 JavaScript 框架来处理跨浏览器的差异是明智之举

一个非常基本的例子是:

var xml = "<music><album>Beethoven</album></music>";

var result = $(xml).find("album").text();

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

请注意,JQuery 不支持 XML 命名空间。zachleat.com/web/2008/05/10/selecting-xml-with-javascript
2021-03-13 03:31:54
抽象出 IE 和其他浏览器之间 XML 解析差异的代码是几行微不足道的,因此不值得单独使用 50K 的 jQuery。操作生成的 XML 的 DOM 是另一回事。
2021-03-19 03:31:54
@SanderVersluys:由于作者不接受其他答案,我会在您的答案中附上一条注释,链接到@TimDown 的正确答案。这样人们就不必阅读所有这些评论来找出正确答案。
2021-03-21 03:31:54
这个答案是错误的。stackoverflow.com/questions/2124924/...stackoverflow.com/questions/2908899/...,@Tim唐氏答案和jQuery文档本身它指出:“需要注意的是[ jQuery()]解析HTML,不是XML”
2021-03-22 03:31:54
在发表我之前的评论时我没有意识到的是,jQuery 甚至不解析 XML,它只是将其分配为innerHTML元素属性,这根本不可靠。
2021-03-24 03:31:54

网络上的大多数示例(以及上面介绍的一些示例)展示了如何以浏览器兼容的方式从文件加载 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;
}
所以现在 IE9+支持 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)') }.
2021-03-15 03:31:54
我知道有关浏览器嗅探的有争议的意见,这就是我没有在此处包含该功能的原因。但是,尚未确定这是错误的。无论如何,这是一个有启发性的例子。
2021-03-30 03:31:54
我相信这是错误的,因为你不能保证它是正确的。任何人都可以欺骗 UA 字符串,并且每个非 IE 浏览器都支持 DOMParser 并且您的浏览器嗅探是否完美是值得怀疑的。此外,以正确的方式做到这一点要容易得多:if(window.ActiveXObject){...}
2021-04-01 03:31:54

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-03-10 03:31:54
自 6/2021 起,请注意不再维护 Marknote。fast-xml-parser 是一个维护的替代方案。
2021-03-17 03:31:54

我一直使用下面的方法在 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);
      }
    }
  }
}
如果您遇到这种情况,您会如何取值 <fruit>value</fruit> ?
2021-03-11 03:31:54
@Siblja 你需要使用innerText而不是getAttribute()
2021-03-31 03:31:54