javascript - 以跨浏览器方式使用 Javascript 的 DOMParser 时,如何检测 XML 解析错误?

标签 javascript xml

似乎所有主流浏览器都实现了 DOMParser API,以便将 XML 解析为 DOM,然后使用 XPath、getElementsByTagName 等进行查询...

然而,检测解析错误似乎更棘手。 DOMParser.prototype.parseFromString总是返回一个有效的 DOM。当发生解析错误时,返回的 DOM 包含一个 <parsererror>元素,但它在每个主要浏览器中略有不同。

示例 JavaScript:

xmlText = '<root xmlns="http://default" xmlns:other="http://other"><child><otherr:grandchild/></child></root>';
parser = new DOMParser();
dom = parser.parseFromString(xmlText, 'application/xml');
console.log((new XMLSerializer()).serializeToString(dom));

Opera 中的结果:

DOM 的根是一个 <parsererror>元素。

<?xml version="1.0"?><parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">Error<sourcetext>Unknown source</sourcetext></parsererror>

Firefox 中的结果:

DOM 的根是一个 <parsererror>元素。

<?xml-stylesheet href="chrome://global/locale/intl.css" type="text/css"?>
<parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">XML Parsing Error: prefix not bound to a namespace
Location: http://fiddle.jshell.net/_display/
Line Number 1, Column 64:<sourcetext>&lt;root xmlns="http://default" xmlns:other="http://other"&gt;&lt;child&gt;&lt;otherr:grandchild/&gt;&lt;/child&gt;&lt;/root&gt;
---------------------------------------------------------------^</sourcetext></parsererror>

Safari 中的结果:

<root>元素解析正确但包含嵌套的 <parsererror>在与 Opera 和 Firefox 的 <parsererror> 不同的命名空间中元素。

<root xmlns="http://default" xmlns:other="http://other"><parsererror xmlns="http://www.w3.org/1999/xhtml" style="display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black"><h3>This page contains the following errors:</h3><div style="font-family:monospace;font-size:12px">error on line 1 at column 50: Namespace prefix otherr on grandchild is not defined
</div><h3>Below is a rendering of the page up to the first error.</h3></parsererror><child><otherr:grandchild/></child></root>

我是否缺少一种简单的跨浏览器方法来检测 XML 文档中是否出现解析错误?或者我必须为每个可能的 <parsererror> 查询 DOM不同浏览器可能生成的元素?

最佳答案

这是我想到的最好的解决方案。

我尝试解析一个故意为无效 XML 的字符串,并观察结果 <parsererror> 的命名空间元素。然后,在解析实际的 XML 时,我可以使用 getElementsByTagNameNS检测同类<parsererror>元素并抛出 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;
};

请注意,此解决方案不包括 Internet Explorer 所需的特殊外壳。然而,在 IE 中事情要简单得多。使用 loadXML 解析 XML如果解析成功或失败,分别返回 true 或 false 的方法。参见 http://www.w3schools.com/xml/xml_parser.asp举个例子。

关于javascript - 以跨浏览器方式使用 Javascript 的 DOMParser 时,如何检测 XML 解析错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11563554/

相关文章:

javascript - 在自定义 React 元素上添加样式属性似乎不起作用

XML 还是自己格式的文件?

javascript - 如何从三种形式之一获取所有复选框?

javascript - Knockout JS 文本输入绑定(bind)

javascript - 如何在 javascript 中模拟 Enter 键按钮

javascript - 使用ajax上传图像仅适用于png

python - 使用 XPath 从表中最左边的列获取 href

c# - 编辑 xml 文件并保留空格和制表符

ruby - 如何使用 Nokogiri 从图像标签中抓取文本?

c# - 无法在 ASP.Net 和 C# 中使用 LINQ 解析 XML