Ver Mensaje Individual
  #1 (permalink)  
Antiguo 28/09/2009, 14:38
thepancher
 
Fecha de Ingreso: noviembre-2008
Mensajes: 67
Antigüedad: 15 años, 5 meses
Puntos: 0
Pregunta Parseando XHTML con Expresiones regulares [Ayuda]

Hola que tal, miren... Ando buscando la forma de analizar archivos xhtml. Y quiero saber si alguien me puede ayudar...

Lo que necesito lograr es extraer los tags de uns archivo xhtml a un array de la siguiente forma... Por ej.

Si el xhtml fuese asi:
Código html:
Ver original
  1.         <head>
  2.                 <title>XHTML</title>
  3.         </head>
  4.         <body>
  5.                 <p class="neat">Lorem ipsum dolor sit amet... </p>
  6.         </body>
  7. </html>

yo necesitaria armar una array que me de la siguiente info. tomo como ejemplo el tag p

Código php:
Ver original
  1.         [5] => array(
  2.                 [tag] => "p",
  3.                 [attributes] => " class=\"neat\"",
  4.                 [value] => "Lorem ipsum dolor sit amet... ",
  5.                 [depth] => "2"
  6.         )
  7. )

para hacer mas simple la explicacion... sme conformo solo con saber como extraer tal info.

estve usando una funcion en la cual utilizo la siguiente expresion regular:
Código php:
Ver original
  1. $pattern = '/\<([a-z0-9\-]+)([^\>]+)?\>((.*)\<\/\1\>)?/';

entonces en la function lo q hago es pasar el/los array(s) por referencia utilizando preg_match_all() algo asi:

Código php:
Ver original
  1. function parse($xhtml, &$array, $depth = 0)
  2. {
  3.         preg_match_all($pattern, $xhtml, $matches);
  4.        
  5.         // con un loop ubico la info de $matches (array_push()) en el array... etc.
  6.         for ($i = 0; $i < count($matches[0]; $i++)) {
  7.                 $array[$i]['tag'] = $matches[1][$i];
  8.                 $array[$i]['attributes'] = $matches[2][$i];
  9.                 $array[$i]['value'] = $matches[4][$i];
  10.                 $array[$i]['depth'] = $depth;
  11.         }
  12.         // y repito la funcion pasandole $xhtml = $matches[4][$i] que si se fijan
  13.         // en la regexp. el subpatron 4 seria el valor del tag y depth sumandole uno
  14.         // ya que marca la profundidad... ej el depth del tag html es 0, el de head
  15.         // y el body es 1, ya que estan dentro del tag html, title y p serian 3, etc.
  16.         parse($matches[4], $array, $depth + 1);
  17. }

he aqui el problem:
supongamos q tenemos un xhtml donde usaron un trukito css para ponerle esquinas redondeadas a un div...
Código html:
Ver original
  1.         <head>
  2.                 <title>XHTML</title>
  3.         </head>
  4.         <body>
  5.                 <div id="container">
  6.                         <div id="c1"></div>
  7.                         <div id="c2"></div>
  8.                         <div id="c3"></div>
  9.                         <div id="c4"></div>
  10.                         <p class="neat">Lorem ipsum dolor sit amet... </p>
  11.                 </div>
  12.         </body>
  13. </html>

se llega a obtener muy buenos resultados, pero cuando queremos parsear el valor del <div id="container"> bienen los problemas...

ya que como valor del <div id="c1"> que tendria que ser nulo o sea "", me da este valor:

Código html:
Ver original
  1. </div>
  2.                         <div id="c2"></div>
  3.                         <div id="c3"></div>
  4.                         <div id="c4">
ya que toma como cierre de la divison el de id="c4"... y si cambio el subpatron 4 del a reg exp. haciendo "ungreedy" como se dice jeje, que quedaria... "... (.*?) ..."

tra problemas al parsear el div id="container" y que como valor del container traeria lo siguiente:

Código html:
Ver original
  1. <div id="c1">

ya que me toma como cierre el primer div... y como los divs se usan muchos en los XHTML, uno dentro de otros, creo que seria imposible analizar uno...

probe haciendo un if dentro de la reg exp. pero cuando se solucion un problem, surge otro xD

a ver si alguien me puede ayudar?

Saludos!

PD: Por favor, si me van a contestar algo como "porque no usas DOM?" o algo asi, directamente no respondan xD ya se que exsite DOM y facilitaria las cosas, pero yo quiero encontrarle la vuelta si o si mas o menos de la forma que digo, con regexps. desde ya, gracias a todos

Última edición por thepancher; 28/09/2009 a las 14:45 Razón: Corregido