Intentando convertir html_string (podría tener más elementos ul li anidados) en ideal_data_output
let html_string = `<ul><li><p>one</p></li><li><p>two</p><ul><li><p>a</p></li><li><p>b</p></li><li><p>c</p></li></ul></li></ul>`; let ideal_data_output = [ { name: 'one' }, { list: [ { name: 'a' }, { name: 'b' }, { name: 'c' } ], name: 'two' } ];Mi intento
// create an array from string let html_tag_array = html_string.split('<'); // function to turn html_tag_array into ideal_data_output const html_to_data = (arr) => { function recursive(data, str_array) { if (str_array == '') return data; let str = str_array.shift(); let temp_obj = { name: null }; if (str.slice(0, 3) == 'ul>') { temp_obj['list'] = []; data.push(temp_obj); return recursive(data[data.length - 1].list, str_array); } if (str.slice(0, 2) == 'p>') { temp_obj.name = str.slice(2); data.push(temp_obj); } return recursive(data, str_array); } return recursive([], arr); };Esto no tiene éxito, lo que da como resultado la salida a continuación.
0: { name: "a" } 1: { name: "b" } 2: { name: "c" } ¿Cuál es la mejor manera de abordar este tipo de problema? Estoy creando un problema con recursive(data[data.length - 1] , ¿cuál es la mejor forma de formatear correctamente esta llamada de función?
Esto debe hacerse con un analizador DOM.
Suponiendo que la estructura HTML siempre tiene el texto en un elemento p separado, y su único nodo hermano siguiente posible es un nodo ul , puede usar esta función recursiva:
const dfs = ul => Array.from(ul.children, ({children: [{textContent: name}, lu]}) => lu ? { list: dfs(lu), name } : { name } ); const html_string = `<ul><li><p>one</p></li><li><p>two</p><ul><li><p>a</p></li><li><p>b</p></li><li><p>c</p></li></ul></li></ul>`; const {body} = new DOMParser().parseFromString(html_string, "text/html"); const result = dfs(body.children[0]); // Assumed to be the UL console.log(result);Esta sencilla solución de búsqueda y reemplazo lo resuelve. Algún truco con las comas, pero no es gran cosa. Ya era una estructura de árbol, por lo que json-ing era factible. Solución más rápida.
var str = ` <ul> <li> <p>one</p> </li> <li> <p>two</p> <ul> <li> <p>a</p> </li> <li> <p>b</p> </li> <li> <p>c</p> </li> </ul> </li> </ul> `; str = str.replace(/<\/p>\s*<ul>/g, '</p>,\n\t\t<ul>'); str = str.replace(/<\/li>\s*<li>/g, '</li>,\n\t\t<li>'); str = str.replace(/<ul>/g, "list: ["); str = str.replace(/<\/ul>/g, "]"); str = str.replace(/<li>/g, "{"); str = str.replace(/<\/li>/g, "}"); str = str.replace(/<p>/g, "name: '"); str = str.replace(/<\/p>/g, "'"); // done! now just prettifying var obj = eval("{" + str + "}") str = JSON.stringify(obj, null, 4); console.log(str) .as-console-wrapper { max-height: 100% !important; }