【001】JS解析,反解析XML的一些问题

JS解析,反解析 XML 的一些问题

2016-03-25 15:38:28 星期五
文章底部下面有提供把 字符串 变成 XML 对象的方法。
该方法,在 Chrome48 ,FireFox ,IE11 测试成功!

  1. stackoverflow XML有命名空间怎么办
  2. 有命名空间的节点,在各个浏览器下有兼容性问题
  3. 解析 字符串 到 XML对象的方法

1. ** stackoverflow XML有命名空间怎么办???**

但是 如果 XML节点,有命名空间,如 <namespace:Node></namespace:Node>
解析就报错,这个报错不是有因为 这个解析方法的问题,而是因为XML格式规定的。

如果XML有使用命名空间的,必须在 root 根节点声明,否则就报错。

如下:

<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
             xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
             id="review-definitions" typeLanguage="http://www.w3.org/2001/XMLSchema"
             expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://activiti.org/bpmn20">
    <activiti:field name="type">
        <activiti:expression>Shell</activiti:expression>
    </activiti:field>
     <bpmndi:BPMNDiagram id="BPMNDiagram_ryantest130">
        <bpmndi:BPMNPlane bpmnElement="ryantest130" id="BPMNPlane_ryantest130">
            <BPMNShape id="BPMNShape_a22f130e-fcfc-411f-8323-f8d0b482d01f"
                       bpmnElement="a22f130e-fcfc-411f-8323-f8d0b482d01f">
                <Bounds height="60" width="60" x="224" y="187"/>
            </BPMNShape>
            <BPMNShape id="BPMNShape_6fa449e4-bfd8-499d-bac0-de62e7b39c4a"
                       bpmnElement="6fa449e4-bfd8-499d-bac0-de62e7b39c4a">
                <Bounds height="60" width="60" x="473" y="194"/>
            </BPMNShape>
            <BPMNShape id="BPMNShape_daf837d7-daeb-4c3b-b820-60cb84b82ddd"
                       bpmnElement="daf837d7-daeb-4c3b-b820-60cb84b82ddd">
                <Bounds height="60" width="60" x="635" y="197"/>
            </BPMNShape>
            <BPMNShape id="BPMNShape_e2df6eed-3b1d-4a6e-b674-8e13364cde29"
                       bpmnElement="e2df6eed-3b1d-4a6e-b674-8e13364cde29">
                <Bounds height="60" width="60" x="227" y="266"/>
            </BPMNShape>
        </bpmndi:BPMNPlane>
    </bpmndi:BPMNDiagram>
</definitions>

2.有命名空间的节点,在各个浏览器下有兼容性问题

Firefox 下:
xmlDoc.getElementTagName('namespace:Node') 这样的方法,在 FireFox 下可以 获取到子节点, 但是,但是 Chrome48 下,拿不到

Chrome48 下:
xmlDoc.getElementTagName('Node') 需要去掉命名空间才可以获取到该节点

提供的解决方案:可以重写 XMLDocument.proptyoe.getElementsTagName

let node = xml.getElementsByTagName('expression');
if (!node.length) node = xml.getElementsByTagName('activiti:expression');

解析 字符串 到 XML对象的方法

var XML = (function() {
    /**
     * 把字符串转换成 XMLDOC 对象
     * @param  {[type]} xmlStr [description]
     * @return {[type]}        [description]
     */
    function str2xml(xmlStr) {
        //跨浏览器,ie和火狐解析xml使用的解析器是不一样的。
        var xmlStrDoc = null;
        if (window.DOMParser) { // Mozilla Explorer
            var parser = new DOMParser();
            xmlStrDoc = parser.parseFromString(xmlStr, "text/xml");
        } else { // Internet Explorer
            xmlStrDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlStrDoc.async = "false";
            xmlStrDoc.loadXML(xmlStr);
        }
        return xmlStrDoc;
    }

    /*===============================XML2JSON START==========================*/
    /**
     * XML 转成 JSON 对象
     * @param  {[type]} xml [description]
     * @return {[type]}     [description]
     */
    function xml2Json(xml) {
        // Create the return object
        var obj = {};
        if (xml.nodeType == 1) { // element
            // do attributes
            if (xml.attributes.length > 0) {
                obj["@attributes"] = {};
                for (var j = 0; j < xml.attributes.length; j++) {
                    var attribute = xml.attributes.item(j);
                    obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
                }
            }
        } else if (xml.nodeType == 3) { // text
            obj = xml.nodeValue;
        }
        // do children
        if (xml.hasChildNodes()) {
            for (var i = 0; i < xml.childNodes.length; i++) {
                var item = xml.childNodes.item(i);
                var nodeName = item.nodeName;
                if (typeof(obj[nodeName]) == "undefined") {
                    obj[nodeName] = xml2Json(item);
                } else {
                    if (typeof(obj[nodeName].length) == "undefined") {
                        var old = obj[nodeName];
                        obj[nodeName] = [];
                        obj[nodeName].push(old);
                    }
                    obj[nodeName].push ? obj[nodeName].push(xml2Json(item)) : obj[nodeName] = xml2Json(item);
                }
            }
        }
        return obj;
    };

    return {
        str2xml: str2xml,
        xml2Json: xml2Json,
    }
})();




posted @   那年、仲夏  阅读(739)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示