Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

214
Vistas
Cómo atravesar y HTML AST en Javascript donde el nodo raíz es en realidad una matriz

Estoy tratando de encontrar la forma correcta de atravesar un HTML AST y encontrar todos los nodos con type: tag y empujarlos a una matriz.

También estoy usando html-parse-stringify para convertir mi HTML en un AST si eso ayuda con algo.

He visto algunos videos sobre cómo atravesar HTML AST en YouTube, pero todos comienzan con un objeto como el nodo de inicio principal, en lugar de comenzar con un Array. Pero duda de que es un gran problema.

El conjunto de datos con los que estoy trabajando son datos raspados de sitios web que luego se convierten en un AST utilizando la biblioteca mencionada anteriormente.

A partir de aquí, solo quiero crear una estructura de bucle básica que pueda atravesar completamente mi AST mientras filtra todos los tipos innecesarios, como text & comment , y luego inserta el objeto correcto en una matriz.

Aquí está la estructura de datos con la que estoy trabajando, he colocado una estructura de datos vacía para facilitar la copia.

También me gustaría reducir el uso de bucles tanto como sea posible por el bien de la complejidad del tiempo.

ingrese la descripción de la imagen aquí

 function mainLoop(node) { Array.prototype.forEach.call(node, parent => { console.log(parent.name); const children = parent.children.filter(n => n.type !== 'text' && n.type !== 'comment'); loop(children) }) } function loop(children) { console.log(children.name) if (children) { Array.prototype.forEach.call(children, child => { loop(child); }) } } mainLoop();

Estructura de datos vacía

 const docTree = [ { attrs: { class: "flex flex-col h-screen", }, children: [ { type: 'tag', name: 'main', attrs: { class: '' }, children: [], } ], name: 'div', type: 'tag', voidElement: false, } ]
about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Si su único objetivo es eliminar texto y comentarios, entonces es bastante sencillo en una sola reducción:

 const traverse = (nodes) => { return nodes.reduce((acc,node) => { if(node.type === 'text' || node.type === 'comment') return acc; return [ ...acc, { ...node, children: traverse(node.children) } ] },[]); }

En realidad no he ejecutado este código, pero creo que funcionará

Si desea aplanar a todos los niños, entonces haga esto:

 const traverse = (nodes) => { return nodes.reduce((acc,{children = [], ...node}) => { if(node.type === 'text' || node.type === 'comment') return acc; return [ ...acc, node, ...traverse(children) ] },[]); }

EDICIÓN 2: Ah, me perdí la parte en la que solo quieres la etiqueta de tipo. Eso se hace con esto:

 const traverse = (nodes) => { return nodes.reduce((acc,{children = [], ...node}) => { if(node.type !== 'tag') return acc; return [ ...acc, node, ...traverse(children) ] },[]); }

Además, no estoy seguro de si desea que los elementos secundarios permanezcan como parte del nodo principal o no. Esto aquí también podría ser lo que quieres:

 const traverse = (nodes) => { return nodes.reduce((acc,node) => { if(node.type !== 'tag') return acc; return [ ...acc, node, ...traverse(node.children) ] },[]); }
about 4 years ago · Juan Pablo Isaza Denunciar

0

Así que creo que he encontrado una solución que estoy buscando. No he terminado de probarlo por completo, pero está en la línea de esto.

Utiliza un bucle externo para recorrer mi matriz inicial de elementos y luego una función recursiva interna para recorrer todos los datos secundarios que estaba buscando y los inserta en una matriz.

 function parentLoop(domAST) { let results = []; Array.prototype.forEach.call(domAST, ele => { function childLoop(node) { const cleaned = node.children.filter(n => n.type !== 'text' && n.type !== 'comment' && n.name !== 'br'); for (let i = 0; i < cleaned.length; i++) { let child = cleaned[i]; if (child.type === 'tag') { results.push(child); } childLoop(child); } } childLoop(ele); }) return results; }

Si hay soluciones mejores o más limpias, todavía estoy abierto a ellas.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda