I'm trying to create valid JSON from the id's of li's in a nested unordered list: e.g here is an example list. Just to clarify I do NOT want to create the UL list, but the JSON from the li id's
<ul >
<li id="p1">1234</li>
<li id="p2">1234
<ul>
<li id="s1">sdfg</li>
<li id="s2">sdfg
<ul>
<li id="sq1">sdfg</li>
<li id="sq2">sdfg</li>
</ul>
</li>
</ul>
</li>
<li id="p6">1234</li>
<li id="p8">1234</li>
</ul>
The JSON should read something like this:
[
{
"item": "p1"
},
{
"item": "p2",
"data": [
{
"item": "s1"
},
{
"item": "s2",
"data": [
{
"item": "sq1"
},
{
"item": "sq2"
}
]
}
]
},
{
"item": "p6"
},
{
"item": "p8"
}
]
I'm trying to create it like this:
let $arr = []
document.querySelectorAll("ul.list li").forEach($li => {
if ($li.querySelector("ul:first-of-type")) {
let $data = [];
$li.querySelectorAll("ul:first-of-type li").forEach($li1 => {
$data.push({ "item": $li1.id })
})
$arr.push({ "item": $li.id, "data": $data })
} else {
$arr.push({ "item": $li.id })
}
})
But it's not creating the correct JSON - any clues / help that creates the correct JSON much appreciated thanks in advance
CodePudding user response:
You'll need to recurse through the tree to build your object, then JSON.stringify
. Here using a simple recursive loop, but you could also look at TreeWalker which is made for traversing the DOM.
function buildTree(parent) {
let result = [];
for (const child of parent.children) {
const data = buildTree(child);
if (child.id === '') {
result = data;
} else {
result.push({ item: child.id, ...(data.length ? { data } : {}) });
}
}
return result;
}
const tree = buildTree(document.querySelector('.list'));
console.log(JSON.stringify(tree, null, 2));
<ul >
<li id="p1">1234</li>
<li id="p2">1234
<ul>
<li id="s1">sdfg</li>
<li id="s2">sdfg
<ul>
<li id="sq1">sdfg</li>
<li id="sq2">sdfg</li>
</ul>
</li>
</ul>
</li>
<li id="p6">1234</li>
<li id="p8">1234</li>
</ul>