Lemme, ага, я тоже так могу.)
Например для второй части вопроса:
function parse(root){
var rootArray = [];
var map = new Map(
Array.from(
root.querySelectorAll('[data-id]'),
element => [
element,
{
name: element.dataset.id,
children: []
}
]
)
);
for(let [element, object] of map){
while((element = element.parentNode) !== root && !map.has(element));
if(element === root) rootArray.push(object);
else map.get(element).children.push(object);
}
return 'id' in root.dataset ? [{
name: root.dataset.id,
children: rootArray
}] : rootArray;
}