【发布时间】:2010-10-13 13:43:59
【问题描述】:
我有一个变量字符串,其中包含格式正确且有效的 XML。我需要使用 JavaScript 代码来解析这个提要。
如何使用(与浏览器兼容的)JavaScript 代码完成此操作?
【问题讨论】:
标签: javascript xml parsing
我有一个变量字符串,其中包含格式正确且有效的 XML。我需要使用 JavaScript 代码来解析这个提要。
如何使用(与浏览器兼容的)JavaScript 代码完成此操作?
【问题讨论】:
标签: javascript xml parsing
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 遍历方法/属性,例如childNodes 和getElementsByTagName() 来获取您想要的节点。
示例用法:
var xml = parseXml("<foo>Stuff</foo>");
alert(xml.documentElement.nodeName);
如果您使用的是 jQuery,从 1.5 版本开始,您可以使用其内置的 parseXML() 方法,其功能与上述功能相同。
var xml = $.parseXML("<foo>Stuff</foo>");
alert(xml.documentElement.nodeName);
【讨论】:
$() for XML parsing。仔细阅读 cmets:它在许多情况下根本不起作用。
parseXML() method 使用字符串。我对更改答案有点谨慎,因为我现在没有简单的方法来测试它。
更新:如需更正确的答案,请参阅 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 会下降,这会测试一切是否按预期解析。
【讨论】:
innerHTML 属性,即一点都不可靠。
jQuery()] 解析 HTML,not XML”
网络上的大多数示例(以及上面介绍的一些示例)展示了如何以与浏览器兼容的方式从文件加载 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;
}
【讨论】:
if(window.ActiveXObject){...}
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)') }。
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") + "'"
);
}
【讨论】:
我一直使用以下在 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);
}
}
}
}
【讨论】:
innerText 而不是getAttribute()
显然 jQuery 现在提供 jQuery.parseXML http://api.jquery.com/jQuery.parseXML/ 从 1.5 版开始
jQuery.parseXML( data )
返回:XMLDocument
【讨论】:
请查看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.
【讨论】:
免责声明:我创建了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 对象。
【讨论】:
<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/
【讨论】:
也可以通过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'))
})
【讨论】: