Python: análisis de documentos XML y preservación de entidades

Quería preguntar qué bibliotecas de Python 2.x existen para analizar un documento XML con DTD incorporado sin expandir automáticamente las entidades. (Archivo en cuestión para aquellos curiosos: JMdict .)

Parece que lxml tiene alguna opción para no analizar las entidades, pero la última vez que lo intenté, las entidades simplemente se convirtieron en espacios en blanco. Simplemente busqué en Google y encontré a pxdom como otra alternativa que puedo probar, pero como es Python puro, parece mucho más lento de lo que me gustaría.

¿Algo más allá afuera?

lxml se menciona en la pregunta y hace lo que usted quiere hasta donde puedo decir. Código de prueba:

 from lxml import etree XML = """  ]>  &abc; """ parser = etree.XMLParser(resolve_entities=False) root = etree.fromstring(XML, parser) print "Entity not resolved:" print etree.tostring(root) print print "Entity resolved:" root = etree.fromstring(XML) print etree.tostring(root) 

Salida:

 Entity not resolved:  &abc;  Entity resolved:  123  

Parece que el caso de uso es bastante anormal; las entidades no en expansión parecen ir en contra de la forma en que se supone que generalmente funcionan los analizadores de acuerdo con la especificación XML.

Por lo tanto, creo que es más fácil simplemente guardar esto tal vez. He extraído manualmente las tags a través de re.finditer, y he hecho un diccionario de las asignaciones. Desde aquí, solo es cuestión de escanear la salida analizada y hacer lo correcto para mi aplicación. Lo suficientemente bueno para mi caso de uso, creo.

Por un lado, BeautifulStoneSoup de BeautifulSoup no expandirá las entidades de manera predeterminada.

Sin embargo, probablemente no sea rápido ni eficiente para su caso de uso, ya que está orientado a un tipo de uso diferente (manejo de todo tipo de marcado mal formado y roto).

Tuve un problema similar para resolver. Necesitaba leer un archivo TEI XML que contiene entidades como

 &some_exotic_char; 

que fueron declarados en un archivo DTD separado. La tarea consistía en agregar algún atributo en ciertas tags y escribir el archivo modificado, preservando las entidades especiales y sin alterar el diseño XML.

BeautifulSoup funcionó bien hasta que quise escribir nuevamente el archivo XML:

 with open('outfile.xml','w') as outfile: outfile.write(soup.prettify()) 

Entonces no dejaría a las entidades «como están», sino que las expandiría en caracteres utf8, que no era lo que yo quería. Además, arruinó el diseño XML original, independientemente del método de prettify (sin él, es aún peor).

Finalmente, me di por vencido y finalmente encontré una buena solución utilizando Perl y XML :: LibXML . Con el metodo

 $parser->expand_entities(0); 

Las entidades no se ampliarán. Y al volver a escribir el XML en un archivo, se mantendrá intacto el diseño original.

 use XML::LibXML; my $parser = new XML::LibXML; $parser->validation(0); $parser->load_ext_dtd(1); $parser->expand_entities(0); my $doc = $parser->parse_file('infile.xml'); ... # do whatever you need to do open my $out, '>', 'outfile.xml'; binmode $out; print $out $doc->toString(); close $out; 

XML de Perl :: LibXML salvó mi día.