在我的文章《 如何在PHP中创建XML到JSON代理服务器》中,我们创建了一个将XML消息转换为支持Ajax的JSON的系统。 如果您正在运行PHP或其他合适的服务器端进程,那就太好了。 但是,如果仅限于JavaScript,该怎么办?
从XML文档中随机访问数据并不有趣。 您可以使用DOM或XPath方法,但是它们不像原生(JSON生成)JavaScript对象属性(例如myobj.list[0].property1
。 如果您经常从同一个XML文档访问数据,将其首先转换为JavaScript对象可能是可行的。 准备编写一些代码了吗?…
XML2jsobj函数
我们将编写一个函数,该函数递归分析XML文档的DOM树的每个节点并返回一个JavaScript对象。 向该函数传递一个起始节点(通常是根documentElement),并返回一个对象(内部命名的数据):
function XML2jsobj(node) {
var data = {};
现在,我们将在XML2jsobj中定义一个Add()函数。 这会将名称/值对附加到数据对象,例如data [name] = value。 但是,如果该名称已经存在,则必须将data [name]转换为数组,以便可以应用两个或多个值:
// append a value
function Add(name, value) {
if (data[name]) {
if (data[name].constructor != Array) {
data[name] = [data[name]];
}
data[name][data[name].length] = value;
}
else {
data[name] = value;
}
};
现在,我们需要一个循环来检查XML节点的属性(例如<node attrib1 =“ 1” attrib2 =“ 2”>),然后使用Add()函数将它们附加到数据对象中:
// element attributes var c, cn; for (c = 0; cn = node.attributes
; c++) {
Add(cn.name, cn.value);
}
The next loop examines all child nodes. Comments and white space are ignored but, if a child contains a single item of textual data, it’s appended to the data object using Add(). If that child has its own children, we recursively call XML2jsobj to generate the object:
// child elements for (c = 0; cn = node.childNodes
; c++) {
if (cn.nodeType == 1) {
if (cn.childNodes.length == 1 && cn.firstChild.nodeType == 3) {
// text value
Add(cn.nodeName, cn.firstChild.nodeValue);
}
else {
// sub-object
Add(cn.nodeName, XML2jsobj(cn));
}
}
}
Finally, we return the data object to our calling function:
return data; }
Converting XML
Our Ajax call can retrieve XML from a web service:
// example XML feed var url = "example.xml"; // AJAX request var xhr = (window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP")); xhr.onreadystatechange = XHRhandler; xhr.open("GET", url, true); xhr.send(null);
Our XMLHttpRequest onreadystatechange handler receives the XML data and converts it to JavaScript object:
// handle response function XHRhandler() { if (xhr.readyState == 4) { var obj = XML2jsobj(xhr.responseXML.documentElement); // do something with our returned data... console.log(obj); xhr = null; } }
So, if example.xml returned the following XML data:
<?xml version="1.0"?> <statuses> <status id="one"> <id>1</id> <text>Hello!</text> </status> </statuses>
XML2jsobj(xhr.responseXML.documentElement) would return the following object:
{ status: { id: ["one", 1], text: "Hello!" } }
You can therefore use obj.status.text to retrieve the “Hello!” text.
Buyer Beware!
A few notes about XML2jsobj:
- XML属性和子元素之间没有区别-如果它们具有相同的名称,则将返回一系列数组,其中属性的索引为0。
- XML2jsobj仅在可行时使用。 如果仅检索一个或两个XML节点值,则使用DOM或XPath方法访问它们将更快。
- 该代码是跨浏览器兼容的(包括IE6),并且可以快速处理大型XML文档。 也就是说,它可能并不适合所有情况。 可能不应该优先使用它来从服务器返回JSON。
抢代码
我希望您觉得它有用-让我知道是否可以缓解一些XML难题!
From: https://www.sitepoint.com/how-to-convert-xml-to-a-javascript-object/