2011-05-17 9 views
8

Estoy buscando un analizador sintáctico que me permita analizar con éxito el xml roto, tomando un enfoque de "mejor estimación", por ejemplo.¿Existe un analizador XML laxo y permisivo para PHP?

<thingy> 
     <description> 
      something <b>with</b> bogus<br> 
      markup not wrapped in CDATA 
     </description> 
    </thingy> 

Lo ideal es que produzca un objeto extraño, con una propiedad de descripción y cualquier etiqueta de sopa dentro.

Otras sugerencias sobre cómo atacar el problema (aparte de tener un marcado válido para empezar) bienvenido.

soluciones no son PHP (Beautiful Soup (Python), por ejemplo) no están fuera de los límites, pero preferiría que se adhieren a la prevaleciente conjunto de habilidades en la empresa

Gracias!

+3

no es XML si es poco estricto ;-) –

+5

No tiene sentido el XML: la idea principal de XML es que lo matará a usted, su familia, sus amigos y cualquier persona con la que haya hablado, si se encuentra con un error de sintaxis. El XML sin manejo de errores draconianos ya no es XML ^^ – NikiC

+3

@nikic - He estado en la misma posición que el OP de tener que lidiar con la entrada "XML" interrumpida proporcionada por un tercero que no entendió el punto de XML. Aunque estoy de acuerdo en que no es ideal, cuando los datos deben ser importados y no podemos lograr que el tercero arregle sus sistemas, solo tenemos que lidiar con eso. :-( – Spudley

Respuesta

4

Puede usar DOMDocument::loadHTML() (o DOMDocument::loadhtmlfile()) para convertir su XML roto al XML correcto. Si no le gusta tratar con objetos DOMDocument, utilice saveXML() y cargue la cadena XML resultante con SimpleXML.

$dom = DOMDocument::loadHTMLfile($filepath); 
if (!$dom) 
{ 
    throw new Exception("Could not load the lax XML file"); 
} 
// Now you can work with your XML file using the $dom object. 


// If you'd like using SimpleXML, do the following steps. 
$xml = new SimpleXML($dom->saveXML()); 
unset($dom); 

He probado este script:

<?php 
$dom = new DOMDocument(); 
$dom->loadHTMLFile('badformatted.xml'); 
if (!$dom) 
{ 
    die('error'); 
} 
$nodes = $dom->getElementsByTagName('description'); 
for ($i = 0; $i < $nodes->length; $i++) 
{ 
    echo "Node content: ".$nodes->item($i)->textContent."\n"; 
} 

La salida al ejecutar esto desde la CLI:

[email protected]:~/xml$ php test.php 

Warning: DOMDocument::loadHTMLFile(): Tag thingy invalid in badformatted.xml, line: 1 in /home/carlos/xml/test.php on line 3 

Warning: DOMDocument::loadHTMLFile(): Tag description invalid in badformatted.xml, line: 2 in /home/carlos/xml/test.php on line 3 
Node content: 
       something with bogus 
       markup not wrapped in CDATA 

[email protected]:~/xml$ 

edición: algunas correcciones menores y el tratamiento de errores.

edit2: Cambie a la llamada no estática para evitar el error E_STRICT, caso de prueba agregado.

+0

Desafortunadamente, ambos fallan: el XML debido al borked XML, el HTML debido a las etiquetas de elemento 'invalid' (para HTML). – Wagemage

+0

En una prueba que he hecho ahora, emite advertencias sobre nodos html desconocidos, pero carga todos los elementos (incluidas estas etiquetas "desconocidas") correctamente. –

+0

consulte mi actualización con un ejemplo con su ejemplo XML –

1

Una alternativa es utilizar la biblioteca Tidy HTML (PHP binding here) para limpiar el HTML primero. Eso sobrevive a una gran cantidad de datos bastante horribles, y he visto a personas usarlo para raspar HTML bastante sobrio antes.

+0

Ese sería mi consejo. Preprocesamiento y una vez que está bien formado, simplemente no lo valida. ¿Asumo que esta es la idea de alguien de una alimentación web RSS? – Mel

+0

La idea de alguien de un catálogo de productos, incluso - bueno, la respuesta de Carlos lo hace, aunque probablemente siga con un ordenamiento HTML como sugieres ...solo para asegurarse de que el marcado interno no bork nada más. – Wagemage

Cuestiones relacionadas