Are there any cross-browser / cross-platform ways to parse XML files in Javascript?
The following will work in all major browsers, including IE 6:
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");
}
Example usage:
var xml = parseXml("<foo>Stuff</foo>");
alert(xml.documentElement.nodeName);
Live demo:
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");
}
var xml = parseXml("<foo>Stuff</foo>");
document.body.innerHTML = "Root element: " + xml.documentElement.nodeName;
Consider using jQuery.parseXML.
Note that old JQuery's code (pre 2.x) is essentially identical to one proposed in the accepted answer and can be found at http://code.jquery.com/jquery-1.9.1.js, partial version below:
// Cross-browser xml parsing
parseXML: function( data ) {
...
try {
if ( window.DOMParser ) { // Standard
tmp = new DOMParser();
xml = tmp.parseFromString( data , "text/xml" );
} else { // IE
xml = new ActiveXObject( "Microsoft.XMLDOM" );
xml.async = "false";
xml.loadXML( data );
}
} catch( e ) {
xml = undefined;
}
...
}
Starting JQuery 2.x code changed to skip ActiveX branch, if you still need it - use older version of JQuery or inline ActiveX parsing. Partial code from http://code.jquery.com/jquery-2.0.0.js:
// Cross-browser xml parsing
parseXML: function( data ) {
var xml, tmp;
.....
// Support: IE9
try {
tmp = new DOMParser();
xml = tmp.parseFromString( data , "text/xml" );
} catch ( e ) {
xml = undefined;
}
.....
},
If you need to parse large XML documents that you may not be able to completely hold in memory, consider using a SAX style parser like this one: https://github.com/isaacs/sax-js/
Related
This is my working piece of code for IE<10, FF and Safari.
var xmlDoc;
function importXML(xmlfile)
{
var element;
var xmlloaded = false;
try
{
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", xmlfile, false);
}
catch (Exception)
{
var ie = (typeof window.ActiveXObject != 'undefined');
if (ie)
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
while(xmlDoc.readyState != 4) {};
IE10 give me error in the following line of code: doesn't support load
xmlDoc.load(xmlfile);
element = xmlDoc.documentElement;
xmlloaded = true;
}
else
{
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.onload = element = xmlDoc.documentElement;
xmlDoc.load(xmlfile);
xmlloaded = true;
}
}
if (!xmlloaded)
{
xmlhttp.setRequestHeader('Content-Type', 'text/xml')
xmlhttp.send("");
xmlDoc = xmlhttp.responseXML;
element = xmlDoc.documentElement;
xmlloaded = true;
}
}
I need this to work with IE 10 too.
I know the solution is here http://blogs.msdn.com/b/ie/archive/2012/07/19/xmlhttprequest-responsexml-in-ie10-release-preview.aspx because in another question on stackvoerflow a user said he found a solution there but he didn't wrote the mod.
I didn't write myself the above code and I'm a beginner so I don't know how to operate.
Javascript can't access the local file system for security reasons. If you have access to the required file and a server of some type, put the file on the server and access it from there using a URL.
I have to extract the content of a tag, here is what I have:
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">iVBORw0KGgoAAAANSUhEUgAAAU0AAAD6CAYAAAAlSBW9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAP+lSURBVHhehP1lnB3H1a4P75Ely8zMzOyYHcccjsNOHNtx7IDtJCbJgtEwM4tG0kgzghnRaEgMI2aWLNlisMVMlgxa73Wv2tvJ85xz ...
</string>
And here is what I want:
iVBORw0KGgoAAAANSUhEUgAAAU0AAAD6CAYAAAAlSBW9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAP+lSURBVHhehP1lnB3H1a4P75Ely8zMzOyYHcccjsNOHNtx7IDtJCbJgtEwM4tG0kgzghnRaEgMI2aWLNlisMVMlgxa73Wv2tvJ85xz ...
I tried with this regexp:
iframeContents.match(/<string[^>]*>(.*?)<\/string>/i);
but I keep getting the string tag and no more the xml one:
<string xmlns="http://tempuri.org/">iVBORw0KGgoAAAANSUhEUgAAAU0AAAD6CAYAAAAlSBW9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAP+lSURBVHhehP1lnB...
Try
iframeContents.match( /<string[^>]*>([\s\S]*?)<\/string>/i )[1]
Match returns an array, or null if there is no match.
The first element of the array is the whole match, the second element is the text matched by the first capture group ().
. doesn't match newlines, but [\s\S] does.
using the parse xml method from here
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");
})
var xml = parseXml("...");
var text = xml.documentElement.firstChild.nodeValue;
I have the following, which loads XML from a web site and parses it:
function load() {
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = parse;
xhttp.open('GET', 'http://...XML.xml', false);
xhttp.send();
}
function parse() {
xmlDoc = xhttp.responseXML.documentElement.childNodes;
for (var i = 0; i < xmlDoc.length; i++) {
nodeName = xmlDoc[i].nodeName;
...
}
After I loading this, I store it in localStorage and I can retrieve it as a string. I need to be able to convert it back to a xml document just like:
xmlDoc = xhttp.responseXML.documentElement.childNodes;
does, so i can parse it. I have been looking for awhile now and can not figure it out.
Thanks in advance.
Based on the answer here XML parsing of a variable string in JavaScript Credit to #tim-down
You need to create an XML parser. Then pass the string into your parse instance. Then you should be able to query it as per before.
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");
}
Example usage:
var xml = parseXml("[Your XML string here]");
I am creating a widget that will be installed across different sites. The widget will parse an XML feed into JPlayer, because the widget will be installed across different sites AJAX is not an option, is there a way to parse XML with javascript without using AJAX. I am trying to stay away from PHP as well.
here is code in Simple XML, but I want to rewrite it in javascript.
$url = 'http://www.startalkradio.net/?page_id=354';
$rss = simplexml_load_file($url);
$items = $rss->channel->item;
<?php
$i = 0;
$data = array();
foreach ($items as $item) {
$data[] = array(
'title' => (string) $item->title,
'mp3' => (string) $item->enclosure['url'],
);
if (++$i == 3) break;
}
$jsdata = json_encode($data);
The following will parse and XML string into an XML document in all major browsers, including IE 6. Once you have that, you can use the usual DOM traversal methods/properties such as childNodes and getElementsByTagName() to get the nodes you want.
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");
}
Example usage:
var xml = parseXml("<foo>Stuff</foo>");
alert(xml.documentElement.nodeName);
I'm using the following parser to parse xml
function parseXML(text) {
var doc;
if(window.DOMParser) {
var parser = new DOMParser();
doc = parser.parseFromString(text, "text/xml");
}
else if(window.ActiveXObject) {
doc = new ActiveXObject("Microsoft.XMLDOM");
doc.async = "false";
doc.loadXML(text);
}
else {
throw new Error("Cannot parse XML");
}
return doc;
}
I can't understand why it isn't working on my XML document, obtained via AJAX.
Result via AJAX request:
X-Powered-By PHP/5.2.11
Content-Length 887
Keep-Alive timeout=5, max=95
Connection Keep-Alive
Content-Type text/xml
<?xml version="1.0" encoding="UTF-8"?>
<xml_test>wont work!</xml_test>
Test Code:
var xml = parseXML(data);
$(xml).find("xml_test").each(function()
{
console.info('found xml_test... never happen..');
});
But if I use it like this it works nicely!
var data = '<xml_test>works</xml_test>';
var xml = parseXML(data);
$(xml).find("xml_test").each(function()
{
alert('this works!');
});
I know that this is a specific question but I would appreciate your help and/or suggestions...
Thanks in advance
Pedro
If you use jQuery to request your resource, you should already get XML DOM document in case it was served with text/xml mime-type. Thus no need to parse.
If you're getting your XML via Ajax, there's no need to parse it because the browser will do it for you. Simply use the responseXML property of the XMLHttpRequest object, which will give you an XML document object. jQuery wraps this using "xml" for the dataType:
$.ajax({
type: "GET",
url: "foo.xml",
dataType: "xml",
success: function(xml) {
alert(xml.documentElement.nodeName);
}
});
I use this function and gives me good result:
var myLoadXml = function(s){
var objxml = null;
if(document.implementation && document.implementation.createDocument) {
var objDOMParser = new DOMParser();
objxml = objDOMParser.parseFromString(s, "text/xml");
} else if (window.ActiveXObject) {
objxml = new ActiveXObject('MSXML2.DOMDocument.3.0');
objxml.async = false;
objxml.loadXML(s);
}
return objxml;
};
var xml = myLoadXml(data);
$(xml).find("xml_test").each(function()
{
console.info('found xml_test... never happen..');
});
EDIT
Example
** EDIT II **
function parseXML(text) {
var doc;
if (typeof text == 'object'){ // check type of text
return text;
}
if(window.DOMParser) {
var parser = new DOMParser();
doc = parser.parseFromString(text, "text/xml");
}
else if(window.ActiveXObject) {
doc = new ActiveXObject("Microsoft.XMLDOM");
doc.async = "false";
doc.loadXML(text);
}
else {
throw new Error("Cannot parse XML");
}
return doc;
}
If you are using jQuery (as your test code suggests), you can simply pass the xml to it.
var xml = $(data);