Nodejs解析XML - xmlreader

专栏收录该内容

Hi I'm Shendi



最近在使用nodejs写微信公众号后台,而公众号发送的消息格式是 xml 的,于是需要使用 nodejs 解析 xml



依赖引入

这里选用了 xmlreader,JSON形式,操作起来非常简单

使用以下命令安装依赖

npm install xmlreader

在代码中引入

var xmlreader = require('xmlreader');


使用示例

var xmlreader = require('xmlreader');
let xmlData = `<xml name='shendi'><ToUserName><![CDATA[1234]]></ToUserName>
<FromUserName><![CDATA[4567]]></FromUserName>
<CreateTime>1693049347</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
<Content><![CDATA[你好2]]></Content>
<infos>
    <name>Shendi</name>
    <site>sdpro.top</site>
</infos>
</xml>`;

// 解析xml字符串
xmlreader.read(xmlData, function (err, res) {
	if (err) {
        console.error(err);
        return;
    }

    // xml节点
    let xml = res.xml;
    // attributes() 获取当前节点的所有属性
    console.log("xml节点的name属性:", xml.attributes().name);
    
    // 和json一样,通过 . 直接获取子节点,FromUserName节点
    let FromUserName = xml.FromUserName;
    // 有CDATA也只获取CDATA里的内容
    console.log("FromUserName节点的内容:", FromUserName.text());
    
    // 有多个节点的没有attributes,text等函数,但是有 array 函数
    let Contents = xml.Content.array;
    console.log("第一个Content内容:", Contents[0].text());
    console.log("第二个Content内容:", Contents[1].text());

    // 多节点也可以通过循环的方式,count()获取数量,at获取指定下标的元素 (但我喜欢直接用array)
    for(var i = 0; i < xml.Content.count(); i++){
        console.log(`for-第 ${i+1} 个Content内容`, xml.Content.at(i).text());
    }

    // 还可以直接foreach
    xml.Content.each(function (i, Content){
        console.log(`foreach-第 ${i+1} 个Content内容`, Content.at(i).text());
    });

    /*
        我截取了一段 info 的数据,parent函数可以拿到父节点
        infos: {
            attributes: [Function: attributes],
            parent: [Function (anonymous)],
            count: [Function (anonymous)],
            at: [Function (anonymous)],
            each: [Function (anonymous)],
            text: [Function (anonymous)],
            name: {
                attributes: [Function: attributes],
                parent: [Function (anonymous)],
                count: [Function (anonymous)],
                at: [Function (anonymous)],
                each: [Function (anonymous)],
                text: [Function (anonymous)]
            },
            site: {
                attributes: [Function: attributes],
                parent: [Function (anonymous)],
                count: [Function (anonymous)],
                at: [Function (anonymous)],
                each: [Function (anonymous)],
                text: [Function (anonymous)]
            }
        }
    */
    // 而如果对于节点是未知的,需要获取节点名称的话,例如上面展示的info
    // 因为是 Object,所以可以通过Object的方式来获取
    let keys = Object.keys(xml.infos);
    for (var i = 0; i < keys.length; i++) {
        let key = keys[i];
        let val = xml.infos[key];
        if (val.text) {
            console.log(`${key}=${val.text()}`);
        }
    }
});

输出结果



API介绍

使用 read 函数解析完xml后,回调函数的 res 参数为 Object 类型,其中只包含根节点,节点的API如下

名称 类型 什么情况存在 描述
count 函数 返回子节点数量
at 函数 返回指定下标的子节点,参数为下标
each 函数 遍历子节点,参数为函数,函数有两参数,第一个为下标,第二个为子节点
array Array 当前节点的名称在同级重复 返回节点列表
attributes 函数 当前节点的名称在同级唯一 返回当前节点的属性列表
parent 函数 当前节点的名称在同级唯一 返回当前节点的父节点
text 函数 当前节点的名称在同级唯一 返回当前节点的节点文本内容,需要注意的是内容为空没有此属性



END

本文链接:https://sdpro.top/blog/html/article/1099.html

♥ 赞助 ♥

尽管去做,或许最终的结果不尽人意,但你不付出,他不付出,那怎会进步呢?