我的 playbook 大部分都起作用了.它将我的XML转换为json.问题是,id属性丢失了.

脚本:

function xml2js(xml)
{
    try
    {
        let obj = {};
        if (xml.children.length == 0)
            obj = xml.textContent;
        else
        {
            for (let i = 0; i < xml.children.length; i++)
            {
                let item = xml.children.item(i);
                let nodeName = item.nodeName;

                if (obj[nodeName])
                {
                    if (typeof (obj[nodeName].push) == "undefined")
                    {
                        let old = obj[nodeName];

                        obj[nodeName] = [];
                        obj[nodeName].push(old);
                    }
                    obj[nodeName].push(xml2js(item));
                }
                else
                {
                    if (item.attributes)
                        for (let attribute of item.attributes)
                            obj[attribute.nodeName] = attribute.nodeValue;

                    obj[nodeName] = xml2js(item);
                }
            }
        }

        return obj;
    }
    catch (e)
    {
        console.log(e.message);
    }
}

我是这样称呼它的

const XMLDoc = (new DOMParser()).parseFromString(XMLString, "text/xml");
console.log(JSON.stringify(xml2js(XMLDoc), null, "\t"));

我的XML

<?xml version="1.0" encoding="UTF-8"?>
<smf>
    <lastTime>1694246241</lastTime>
    <topic id="78603">
        <icon><![CDATA[<div class="board_icon"><img src="http://localhost/SMF2.1/Themes/default/images/post/xx.png" alt=""></div>]]></icon>
        <subject>&lt;a href=&quot;http://localhost/SMF2.1/index.php?topic=78603.0&quot;&gt;Automated Test #14561&lt;/a&gt;&lt;br&gt;Started by &lt;a href=&quot;http://localhost/SMF2.1/index.php?action=profile;u=10&quot;&gt;Member 10&lt;/a&gt;  </subject>
        <board>&lt;a href=&quot;http://localhost/SMF2.1/index.php?board=51.0&quot;&gt;Board Number 51&lt;/a&gt;</board>
        <replies><![CDATA[7 Replies<br>8 Views]]>></replies>
        <lastPost>
            <time ts="1694246241"><![CDATA[<strong>Today</strong> at 12:57 AM]]></time>
            <link><![CDATA[by <a href="http://localhost/SMF2.1/index.php?action=profile;u=1">live627</a>D <a href="http://localhost/SMF2.1/index.php?topic=78603.new;topicseen#new" class="new_posts">New</a>]]></link>
        </lastPost>
    </topic>
    <topic id="78604">
        <icon><![CDATA[<div class="board_icon"><img src="http://localhost/SMF2.1/Themes/default/images/post/xx.png" alt=""></div>]]></icon>
        <subject>&lt;a href=&quot;http://localhost/SMF2.1/index.php?topic=78604.0&quot;&gt;Automated Test #14562&lt;/a&gt;&lt;br&gt;Started by &lt;a href=&quot;http://localhost/SMF2.1/index.php?action=profile;u=10&quot;&gt;Member 10&lt;/a&gt;  </subject>
        <board>&lt;a href=&quot;http://localhost/SMF2.1/index.php?board=51.0&quot;&gt;Board Number 51&lt;/a&gt;</board>
        <replies><![CDATA[0 Replies<br>0 Views]]>></replies>
        <lastPost>
            <time ts="1693697618"><![CDATA[Sep 02, 2023, 04:33 PM]]></time>
            <link><![CDATA[by <a href="http://localhost/SMF2.1/index.php?action=profile;u=10">Member 10</a>D <a href="http://localhost/SMF2.1/index.php?topic=78604.new;topicseen#new" class="new_posts">New</a>]]></link>
        </lastPost>
    </topic>
    <topic id="78602">
        <icon><![CDATA[<div class="board_icon"><img src="http://localhost/SMF2.1/Themes/default/images/post/xx.png" alt=""></div>]]></icon>
        <subject>&lt;a href=&quot;http://localhost/SMF2.1/index.php?topic=78602.0&quot;&gt;Automated Test #14560&lt;/a&gt;&lt;br&gt;Started by &lt;a href=&quot;http://localhost/SMF2.1/index.php?action=profile;u=10&quot;&gt;Member 10&lt;/a&gt;  </subject>
        <board>&lt;a href=&quot;http://localhost/SMF2.1/index.php?board=51.0&quot;&gt;Board Number 51&lt;/a&gt;</board>
        <replies><![CDATA[0 Replies<br>0 Views]]>></replies>
        <lastPost>
            <time ts="1693697618"><![CDATA[Sep 02, 2023, 04:33 PM]]></time>
            <link><![CDATA[by <a href="http://localhost/SMF2.1/index.php?action=profile;u=10">Member 10</a>D <a href="http://localhost/SMF2.1/index.php?topic=78602.new;topicseen#new" class="new_posts">New</a>]]></link>
        </lastPost>
    </topic>
</smf>

预期yields

{
    "smf": {
        "lastTime": "1694246241",
        "topic": [
            {
                "id": "78603",
                "icon": "<div class=\"board_icon\"><img src=\"http://localhost/SMF2.1/Themes/default/images/post/xx.png\" alt=\"\"></div>",
                "subject": "<a href=\"http://localhost/SMF2.1/index.php?topic=78603.0\">Automated Test #14561</a><br>Started by <a href=\"http://localhost/SMF2.1/index.php?action=profile;u=10\">Member 10</a>  ",
                "board": "<a href=\"http://localhost/SMF2.1/index.php?board=51.0\">Board Number 51</a>",
                "replies": "7 Replies<br>8 Views>",
                "lastPost": {
                    "ts": "1694246241",
                    "time": "Sep 09, 2023, 12:57 AM",
                    "link": "by <a href=\"http://localhost/SMF2.1/index.php?action=profile;u=1\">live627</a>D <a href=\"http://localhost/SMF2.1/index.php?topic=78603.new;topicseen#new\" class=\"new_posts\">New</a>"
                }
            },
            {
                "id": "78604",
                "icon": "<div class=\"board_icon\"><img src=\"http://localhost/SMF2.1/Themes/default/images/post/xx.png\" alt=\"\"></div>",
                "subject": "<a href=\"http://localhost/SMF2.1/index.php?topic=78604.0\">Automated Test #14562</a><br>Started by <a href=\"http://localhost/SMF2.1/index.php?action=profile;u=10\">Member 10</a>  ",
                "board": "<a href=\"http://localhost/SMF2.1/index.php?board=51.0\">Board Number 51</a>",
                "replies": "0 Replies<br>0 Views>",
                "lastPost": {
                    "ts": "1693697618",
                    "time": "Sep 02, 2023, 04:33 PM",
                    "link": "by <a href=\"http://localhost/SMF2.1/index.php?action=profile;u=10\">Member 10</a>D <a href=\"http://localhost/SMF2.1/index.php?topic=78604.new;topicseen#new\" class=\"new_posts\">New</a>"
                }
            },
            {
                "id": "78602",
                "icon": "<div class=\"board_icon\"><img src=\"http://localhost/SMF2.1/Themes/default/images/post/xx.png\" alt=\"\"></div>",
                "subject": "<a href=\"http://localhost/SMF2.1/index.php?topic=78602.0\">Automated Test #14560</a><br>Started by <a href=\"http://localhost/SMF2.1/index.php?action=profile;u=10\">Member 10</a>  ",
                "board": "<a href=\"http://localhost/SMF2.1/index.php?board=51.0\">Board Number 51</a>",
                "replies": "0 Replies<br>0 Views>",
                "lastPost": {
                    "ts": "1693697618",
                    "time": "Sep 02, 2023, 04:33 PM",
                    "link": "by <a href=\"http://localhost/SMF2.1/index.php?action=profile;u=10\">Member 10</a>D <a href=\"http://localhost/SMF2.1/index.php?topic=78602.new;topicseen#new\" class=\"new_posts\">New</a>"
                }
            }
        ]
    }
}

实际yields

{
    "smf": {
        "lastTime": "1694246241",
        "id": "78603",
        "topic": [
            {
                "icon": "<div class=\"board_icon\"><img src=\"http://localhost/SMF2.1/Themes/default/images/post/xx.png\" alt=\"\"></div>",
                "subject": "<a href=\"http://localhost/SMF2.1/index.php?topic=78603.0\">Automated Test #14561</a><br>Started by <a href=\"http://localhost/SMF2.1/index.php?action=profile;u=10\">Member 10</a>  ",
                "board": "<a href=\"http://localhost/SMF2.1/index.php?board=51.0\">Board Number 51</a>",
                "replies": "7 Replies<br>8 Views>",
                "lastPost": {
                    "ts": "1694246241",
                    "time": "<strong>Today</strong> at 12:57 AM",
                    "link": "by <a href=\"http://localhost/SMF2.1/index.php?action=profile;u=1\">live627</a>D <a href=\"http://localhost/SMF2.1/index.php?topic=78603.new;topicseen#new\" class=\"new_posts\">New</a>"
                }
            },
            {
                "icon": "<div class=\"board_icon\"><img src=\"http://localhost/SMF2.1/Themes/default/images/post/xx.png\" alt=\"\"></div>",
                "subject": "<a href=\"http://localhost/SMF2.1/index.php?topic=78604.0\">Automated Test #14562</a><br>Started by <a href=\"http://localhost/SMF2.1/index.php?action=profile;u=10\">Member 10</a>  ",
                "board": "<a href=\"http://localhost/SMF2.1/index.php?board=51.0\">Board Number 51</a>",
                "replies": "0 Replies<br>0 Views>",
                "lastPost": {
                    "ts": "1693697618",
                    "time": "Sep 02, 2023, 04:33 PM",
                    "link": "by <a href=\"http://localhost/SMF2.1/index.php?action=profile;u=10\">Member 10</a>D <a href=\"http://localhost/SMF2.1/index.php?topic=78604.new;topicseen#new\" class=\"new_posts\">New</a>"
                }
            },
            {
                "icon": "<div class=\"board_icon\"><img src=\"http://localhost/SMF2.1/Themes/default/images/post/xx.png\" alt=\"\"></div>",
                "subject": "<a href=\"http://localhost/SMF2.1/index.php?topic=78602.0\">Automated Test #14560</a><br>Started by <a href=\"http://localhost/SMF2.1/index.php?action=profile;u=10\">Member 10</a>  ",
                "board": "<a href=\"http://localhost/SMF2.1/index.php?board=51.0\">Board Number 51</a>",
                "replies": "0 Replies<br>0 Views>",
                "lastPost": {
                    "ts": "1693697618",
                    "time": "Sep 02, 2023, 04:33 PM",
                    "link": "by <a href=\"http://localhost/SMF2.1/index.php?action=profile;u=10\">Member 10</a>D <a href=\"http://localhost/SMF2.1/index.php?topic=78602.new;topicseen#new\" class=\"new_posts\">New</a>"
                }
            }
        ]
    }
}

注意应该如何按照预期将id元素添加到topic个对象中,但却错误地将其添加到顶级对象中.

推荐答案

  • 重新排列代码,以便将属性添加到当前 node ,而不是父 node ,此外还需要将属性添加到同级 node .

  • 利用迭代器对子对象和属性进行循环.

  • 此外,当文本 node 没有属性时,您可能会有一些设计缺陷.也许这没什么问题.

const XMLDoc = (new DOMParser()).parseFromString(XMLString, "text/xml");
$pre.textContent = JSON.stringify(xml2js(XMLDoc), null, 4);

function xml2js(node){
    try {

        // collect attributes first
        const obj = [...node.attributes || []].reduce((r, attr) => (r[attr.nodeName] = attr.value, r), {});

        if (!node.children.length) {
            obj.content = node.textContent;
        } else
        
        for (const item of node.children){
            const {nodeName} = item, child = obj[nodeName];
            child ? 
              (Array.isArray(child) ? child : obj[nodeName] = [child]).push(xml2js(item)) : 
              obj[nodeName] = xml2js(item);
        }

        return obj;
        
    } catch (e) {
        console.log(e.message);
    }
}
<script>
const XMLString = `<?xml version="1.0" encoding="UTF-8"?>
<smf>
    <lastTime>1694246241</lastTime>
    <topic id="78603">
        <icon><![CDATA[<div class="board_icon"><img src="http://localhost/SMF2.1/Themes/default/images/post/xx.png" alt=""></div>]]></icon>
        <subject>&lt;a href=&quot;http://localhost/SMF2.1/index.php?topic=78603.0&quot;&gt;Automated Test #14561&lt;/a&gt;&lt;br&gt;Started by &lt;a href=&quot;http://localhost/SMF2.1/index.php?action=profile;u=10&quot;&gt;Member 10&lt;/a&gt;  </subject>
        <board>&lt;a href=&quot;http://localhost/SMF2.1/index.php?board=51.0&quot;&gt;Board Number 51&lt;/a&gt;</board>
        <replies><![CDATA[7 Replies<br>8 Views]]>></replies>
        <lastPost>
            <time ts="1694246241"><![CDATA[<strong>Today</strong> at 12:57 AM]]></time>
            <link><![CDATA[by <a href="http://localhost/SMF2.1/index.php?action=profile;u=1">live627</a>D <a href="http://localhost/SMF2.1/index.php?topic=78603.new;topicseen#new" class="new_posts">New</a>]]></link>
        </lastPost>
    </topic>
    <topic id="78604">
        <icon><![CDATA[<div class="board_icon"><img src="http://localhost/SMF2.1/Themes/default/images/post/xx.png" alt=""></div>]]></icon>
        <subject>&lt;a href=&quot;http://localhost/SMF2.1/index.php?topic=78604.0&quot;&gt;Automated Test #14562&lt;/a&gt;&lt;br&gt;Started by &lt;a href=&quot;http://localhost/SMF2.1/index.php?action=profile;u=10&quot;&gt;Member 10&lt;/a&gt;  </subject>
        <board>&lt;a href=&quot;http://localhost/SMF2.1/index.php?board=51.0&quot;&gt;Board Number 51&lt;/a&gt;</board>
        <replies><![CDATA[0 Replies<br>0 Views]]>></replies>
        <lastPost>
            <time ts="1693697618"><![CDATA[Sep 02, 2023, 04:33 PM]]></time>
            <link><![CDATA[by <a href="http://localhost/SMF2.1/index.php?action=profile;u=10">Member 10</a>D <a href="http://localhost/SMF2.1/index.php?topic=78604.new;topicseen#new" class="new_posts">New</a>]]></link>
        </lastPost>
    </topic>
    <topic id="78602">
        <icon><![CDATA[<div class="board_icon"><img src="http://localhost/SMF2.1/Themes/default/images/post/xx.png" alt=""></div>]]></icon>
        <subject>&lt;a href=&quot;http://localhost/SMF2.1/index.php?topic=78602.0&quot;&gt;Automated Test #14560&lt;/a&gt;&lt;br&gt;Started by &lt;a href=&quot;http://localhost/SMF2.1/index.php?action=profile;u=10&quot;&gt;Member 10&lt;/a&gt;  </subject>
        <board>&lt;a href=&quot;http://localhost/SMF2.1/index.php?board=51.0&quot;&gt;Board Number 51&lt;/a&gt;</board>
        <replies><![CDATA[0 Replies<br>0 Views]]>></replies>
        <lastPost>
            <time ts="1693697618"><![CDATA[Sep 02, 2023, 04:33 PM]]></time>
            <link><![CDATA[by <a href="http://localhost/SMF2.1/index.php?action=profile;u=10">Member 10</a>D <a href="http://localhost/SMF2.1/index.php?topic=78602.new;topicseen#new" class="new_posts">New</a>]]></link>
        </lastPost>
    </topic>
</smf>`
</script>
<pre id="$pre"></pre>

Javascript相关问答推荐

未使用React功能组件中的最新状态的功能

Tailwind-Elements React集成到ClojureScript

类型错误:tasks.map不是函数(MERN堆栈)

如何expose 像React在onChange、onClick等中所做的那样的参数?

Next.js Next/Image图像隐含性有任何类型-如何修复?

如何修复内容安全策略指令脚本-SRC自身错误?

确定MutationRecord中removedNodes的索引

fs. writeFile()vs fs.writeFile()vs fs.appendFile()

我可以使用CSS有效地实现最大宽度=100%和最大高度=100%,而无需父母有明确的/固定的宽度和高度,替代方法吗?

如何解决chrome—extension代码中的错误,它会实时覆盖google—meet的面部图像?'

并不是所有的iframe都被更换

在使用HighChats时如何避免Datatables重新初始化错误?

对路由DOM嵌套路由作出react

更新动态数据中对象或数组中的所有值字符串

Node.js错误: node 不可单击或不是元素

通过跳过某些元素的对象进行映射

构建器模式与参数对象输入

如何修复错误&语法错误:不能在纯react 项目中JEST引发的模块&之外使用导入语句?

P5JS-绘制不重叠的圆

如何在独立的Angular 应用程序中添加Lucide-Angel?