Cross-Browser Javascript XML Parsing
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;
Cross-Browser Javascript Parser for XML with Namespace
You could try another approach, by converting the XML to JSON server side, using a generic XSLT like http://code.google.com/p/xml2json-xslt/, and deliver to the browser only JSON.
It will add up a small overhead on the server response, but nothing compared to the amount of code and time spent on the browser to render XML.
With the exception of IE, with its impressive msxml, I think reading XML in common browsers is a real pain compared to JSON.
Parse XML using JavaScript
I'm guessing from your last question, asked 20 minutes before this one, that you are trying to parse (read and convert) the XML found through using GeoNames' FindNearestAddress.
If your XML is in a string variable called txt
and looks like this:
<address>
<street>Roble Ave</street>
<mtfcc>S1400</mtfcc>
<streetNumber>649</streetNumber>
<lat>37.45127</lat>
<lng>-122.18032</lng>
<distance>0.04</distance>
<postalcode>94025</postalcode>
<placename>Menlo Park</placename>
<adminCode2>081</adminCode2>
<adminName2>San Mateo</adminName2>
<adminCode1>CA</adminCode1>
<adminName1>California</adminName1>
<countryCode>US</countryCode>
</address>
Then you can parse the XML with Javascript DOM like this:
if (window.DOMParser)
{
parser = new DOMParser();
xmlDoc = parser.parseFromString(txt, "text/xml");
}
else // Internet Explorer
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(txt);
}
And get specific values from the nodes like this:
//Gets house address number
xmlDoc.getElementsByTagName("streetNumber")[0].childNodes[0].nodeValue;
//Gets Street name
xmlDoc.getElementsByTagName("street")[0].childNodes[0].nodeValue;
//Gets Postal Code
xmlDoc.getElementsByTagName("postalcode")[0].childNodes[0].nodeValue;
JSFiddle
Feb. 2019 edit:
In response to @gaugeinvariante's concerns about xml with Namespace prefixes.
Should you have a need to parse xml with Namespace prefixes, everything should work almost identically:
NOTE: this will only work in browsers that support xml namespace prefixes such as Microsoft Edge
// XML with namespace prefixes 's', 'sn', and 'p' in a variable called txt
txt = `
<address xmlns:p='example.com/postal' xmlns:s='example.com/street' xmlns:sn='example.com/streetNum'>
<s:street>Roble Ave</s:street>
<sn:streetNumber>649</sn:streetNumber>
<p:postalcode>94025</p:postalcode>
</address>`;
//Everything else the same
if (window.DOMParser)
{
parser = new DOMParser();
xmlDoc = parser.parseFromString(txt, "text/xml");
}
else // Internet Explorer
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(txt);
}
//The prefix should not be included when you request the xml namespace
//Gets "streetNumber" (note there is no prefix of "sn"
console.log(xmlDoc.getElementsByTagName("streetNumber")[0].childNodes[0].nodeValue);
//Gets Street name
console.log(xmlDoc.getElementsByTagName("street")[0].childNodes[0].nodeValue);
//Gets Postal Code
console.log(xmlDoc.getElementsByTagName("postalcode")[0].childNodes[0].nodeValue);
Crossbrowser XML manipulation and parse with XSL (Chrome, Firefoz and IE 8/11)
See https://msdn.microsoft.com/en-us/library/dn423948(v=vs.85).aspx, in IE 11 you need to use new ActiveXObject('program.id')
inside of a try/catch, the check for the window property does not work.
Furthermore, the native IE DOM documents you create with DOMParser in IE do not support transformNode
, so if you know you need an XML DOM document in IE to do XSLT transformation then you need to make sure you create an MSXML DOM document with new ActiveXObject
and you need to do try to do that first in your code with try/catch, before you try to instantiate DOMParser.
So for the XML parsing from a string I would use
function getXmlDom(content) {
var xmlDom;
try {
xmlDom = new ActiveXObject('Msxml2.DOMDocument.6.0');
xmlDom.loadXML(content);
}
catch (e) {
try {
xmlDom = new ActiveXObject('Msxml2.DOMDocument.3.0');
xmlDom.loadXML(content);
}
catch (e2) {
xmlDom = (new DOMParser()).parseFromString(content, 'application/xml');
}
}
return xmlDom;
}
as done in http://home.arcor.de/martin.honnen/javascript/2016/test2016022301.html.
How do I detect XML parsing errors when using Javascript's DOMParser in a cross-browser way?
This is the best solution I've come up with.
I attempt to parse a string that is intentionally invalid XML and observe the namespace of the resulting <parsererror>
element. Then, when parsing actual XML, I can use getElementsByTagNameNS
to detect the same kind of <parsererror>
element and throw a Javascript Error
.
// My function that parses a string into an XML DOM, throwing an Error if XML parsing fails
function parseXml(xmlString) {
var parser = new DOMParser();
// attempt to parse the passed-in xml
var dom = parser.parseFromString(xmlString, 'application/xml');
if(isParseError(dom)) {
throw new Error('Error parsing XML');
}
return dom;
}
function isParseError(parsedDocument) {
// parser and parsererrorNS could be cached on startup for efficiency
var parser = new DOMParser(),
errorneousParse = parser.parseFromString('<', 'application/xml'),
parsererrorNS = errorneousParse.getElementsByTagName("parsererror")[0].namespaceURI;
if (parsererrorNS === 'http://www.w3.org/1999/xhtml') {
// In PhantomJS the parseerror element doesn't seem to have a special namespace, so we are just guessing here :(
return parsedDocument.getElementsByTagName("parsererror").length > 0;
}
return parsedDocument.getElementsByTagNameNS(parsererrorNS, 'parsererror').length > 0;
};
Note that this solution doesn't include the special-casing needed for Internet Explorer. However, things are much more straightforward in IE. XML is parsed with a loadXML
method which returns true or false if parsing succeeded or failed, respectively. See http://www.w3schools.com/xml/xml_parser.asp for an example.
Parsing an xml tag with JavaScript
Your xml is not well formed. An xml element can have either text or child elements as content. Instead, try this
<system os="Xp">
<version>1.9</version>
<version>2.0</version>
</system>
or that
<system>
<os>Xp</os>
<version>1.9</version>
<version>2.0</version>
</system>
Related Topics
State Not Updating When Using React State Hook Within Setinterval
What Is This JavaScript "Require"
Why Does Chrome Debugger Think Closed Local Variable Is Undefined
Why Use Named Function Expressions
Managing Jquery Plugin Dependency in Webpack
Angularjs: How to Pass Variables Between Controllers
JavaScript Implementation of Gzip
"Syntaxerror: Unexpected Token ≪ in Json At Position 0"
Controller Not a Function, Got Undefined, While Defining Controllers Globally
How to Check For a #Hash in a Url Using JavaScript
How to Set the Caret (Cursor) Position in a Contenteditable Element (Div)
How to Avoid 'Cannot Read Property of Undefined' Errors
Module.Exports VS Exports in Node.Js
How to Bind to List of Checkbox Values with Angularjs
How to Communicate Between Related React Components
Generating PDF Files with JavaScript
JavaScript Es6 Promise for Loop
How to Transition the Flex-Grow of a Flex Box to Produce an Animation