XML 到 JavaScript 对象

IT技术 javascript xml json
2021-02-16 01:00:31

我正在寻找一个解析 XML 字符串并将其转换为 JavaScript 对象的 JavaScript 库。有哪些好的?

5个回答

以下函数解析 XML 并返回一个具有与 XML 对应的方案的 JavaScript 对象。具有相同名称的 XML 兄弟姐妹被折叠到数组中。具有可以在arrayTags参数(标签名称字符串数组)中找到的名称的节点总是生成数组,即使只有一个标签出现。arrayTags可以省略。只有空格的文本节点被丢弃。

function parseXml(xml, arrayTags) {
    let dom = null;
    if (window.DOMParser) dom = (new DOMParser()).parseFromString(xml, "text/xml");
    else if (window.ActiveXObject) {
        dom = new ActiveXObject('Microsoft.XMLDOM');
        dom.async = false;
        if (!dom.loadXML(xml)) throw dom.parseError.reason + " " + dom.parseError.srcText;
    }
    else throw new Error("cannot parse xml string!");

    function parseNode(xmlNode, result) {
        if (xmlNode.nodeName == "#text") {
            let v = xmlNode.nodeValue;
            if (v.trim()) result['#text'] = v;
            return;
        }

        let jsonNode = {},
            existing = result[xmlNode.nodeName];
        if (existing) {
            if (!Array.isArray(existing)) result[xmlNode.nodeName] = [existing, jsonNode];
            else result[xmlNode.nodeName].push(jsonNode);
        }
        else {
            if (arrayTags && arrayTags.indexOf(xmlNode.nodeName) != -1) result[xmlNode.nodeName] = [jsonNode];
            else result[xmlNode.nodeName] = jsonNode;
        }

        if (xmlNode.attributes) for (let attribute of xmlNode.attributes) jsonNode[attribute.nodeName] = attribute.nodeValue;

        for (let node of xmlNode.childNodes) parseNode(node, jsonNode);
    }

    let result = {};
    for (let node of dom.childNodes) parseNode(node, result);

    return result;
}
@MaylowHayes 在 IE11 中使用时会产生脚本错误。有任何想法吗?
2021-04-19 01:00:31
每个节点的文本节点都是空的:(
2021-04-30 01:00:31
也看看我在那里的改进
2021-05-01 01:00:31
嗨梅洛,欢迎来到 SO,如果您能提供一个简短的描述以及您的答案,将会更有帮助,
2021-05-04 01:00:31
这是非常有帮助的。干得好,谢谢。
2021-05-13 01:00:31
Goessner 库的问题在于它返回一个 JSON 字符串。您最终会将 XML 字符串转换为 JSON 字符串,然后您必须再次解析该字符串以获得实际的 Javascript 对象。它会起作用,但可能有更有效的方法。
2021-05-10 01:00:31

直奔主题(使用node-xml2json):

npm install xml2json

然后,使用它:

const parser = require('xml2json');

const obj = parser.toJson(xml, { object: true });

例子:

const parser = require('xml2json');

const xml = '<root><person><name>Bob Dylan</name></person></root>';

const obj = parser.toJson(xml, { object: true });
const { person } = obj.root;
person.name; // Bob Dylan

您还可以从 JSON 转换为 XML,等等

我想要一个简单的 Typescript 版本,它不会创建额外的 #text 对象,也不会忽略属性。如果这就是你需要的,这里是代码:

export class DomFuncs {

    static parseNode = (node: Node) => {    
        const childNodes = node.childNodes;
        if (childNodes.length === 0) {
            return node.nodeValue;
        } else if (childNodes.length === 1 && childNodes[0].nodeType === Node.TEXT_NODE) {
            return childNodes[0].nodeValue;
        } else {
            const obj = {};
            childNodes.forEach(childNode => {
                const childName = childNode.nodeName;
                const childValue = obj[childName];
                if (childValue !== undefined) {
                    if (Array.isArray(childValue)) {
                        childValue.push(DomFuncs.parseNode(childNode));
                    } else {
                        obj[childName] = [childValue, DomFuncs.parseNode(childNode)];
                    }
                } else {
                    obj[childName] = DomFuncs.parseNode(childNode);
                }
            });
            return obj;
        }
    };

    static xml2obj = (str: string) => {
        const dom = (new DOMParser()).parseFromString(str, 'text/xml')
        const result = {[dom.nodeName]: DomFuncs.parseNode(dom)};
        return result;
    }
}

要使用它:

DomFuncs.xml2obj(xmlString);

该脚本目前不考虑 XML 属性,因为我转换的对象不需要它们。如果您需要,请告诉我,我可以更新代码。

来自https://bitbucket.org/surenrao/xml2json的 xml2json javascript 文件是您执行此操作所需的全部内容。

这是快速下载的下载链接:https : //bitbucket.org/surenrao/xml2json/get/0e0989dfe48e.zip

一旦包含在您的项目中,这里有一些示例代码可以帮助您入门:

var xmlStr = "<root><person><name>Bob Dylan</name></person></root>";
var jsObj = X2J.parseXml(xmlStr);
var result = jsObj[0].root[0].person[0].name[0].jValue; //Bob Dylan