8
votes

Python LibxML2 Reader et XML_PARSE_RECOVER

J'essaie d'obtenir un lecteur de récupérer de XML cassé. Utilisation de l'option libxml2.xml_parse_recover avec les travaux Dom API (LibXML2.Readdoc) et il récupère des problèmes d'entité.

Cependant, en utilisant l'option avec l'API de lecteur (essentiel en raison de la taille des documents que nous analysons) travail. Il suffit de rester coincé dans une boucle perpétuelle (avec lave-lecture () renvoyant -1): p>

code d'échantillon (avec petit exemple): P>

import cStringIO
import libxml2

DOC = "<a>some broken & xml</a>"

reader = libxml2.readerForDoc(DOC, "urn:bogus", None, libxml2.XML_PARSE_RECOVER | libxml2.XML_PARSE_NOERROR)

ret = reader.Read()
while ret:
    print 'ret: %d' % ret
    print "node name: ", reader.Name(), reader.NodeType()
    ret = reader.Read()


2 commentaires

Oui: pendant que RET == 1: . Voir xmlsoft.org/xmlreader.html .


Merci mais cela ne récupère pas, juste abandonne. Donc, pour ce qui précède, je ne recevais que le tag .Le Dom API entraîne un arbre de document avec la récupération qui dépose simplement le & - qui est idéalement ce que j'aimerais (équivalent) à partir de l'API Reader.


4 Réponses :


1
votes

Je ne suis pas trop sûr de l'état actuel des liaisons LibxML2. Même le site LibXML2 suggère d'utiliser lxml à la place. Pour analyser cet arbre et ignorer le & code> est bien et propre dans lxml: xxx pré>

le page d'analyseurs dans les documents LXML passe plus en détail sur la mise en place d'un analyseur et itérant sur le contenu. P>

EDIT: P>

Si vous souhaitez analyser progressivement un document, la classe XMLParser peut être utilisée aussi bien qu'elle est une sous-classe de _feedParser code>: p >

DOC = "<a>some broken & xml</a>"
reader = etree.XMLParser(recover=True)

for data in StringIO(DOC).read():
    reader.feed(data)

tree = reader.close()
print etree.tostring(tree)


3 commentaires

Malheureusement, j'ai aussi examiné la LXML, mais votre suggestion ci-dessus utilise l'API DOM, en raison de la taille des documents qui n'est pas une option. L'API LXML IterParse ne prend pas en charge la récupération.


Si vous n'essayez pas d'analyser progressivement, examinez l'interface _feedParser pour LXML, je modifierai l'échantillon ci-dessus avec son utilisation. Je n'ai pas été en mesure de trouver une méthode itérative pour analyser ce qui donne des éléments tels qu'ils sont analysés. codespace.net/lxml/api/lxml.etree._feedParser-class. HTML


Merci pour tous vos efforts. Techniquement, ce dont nous avons besoin, c'est à la fois un analysement progressif et une traction d'éléments entraînés par des événements avec récupération. La honte LXML ne correspond pas à ces exigences.



0
votes

Le XML n'est-il pas cassé de manière cohérente? N'y a-t-il pas de modèle que vous pourriez suivre pour réparer votre XML avant d'analyser?

Par exemple - Si l'erreur est provoquée uniquement par des ampersands non évaluées et que vous n'utilisez pas de CDATA ou d'instructions de traitement, il peut être réparé avec un regexp.

Edit: Regardez ensuite SGMLLIB dans la bibliothèque standard Python. Beautifulsoup l'utilise, il peut donc être utile dans votre cas. (Betifulsoup lui-même offre uniquement la représentation des arbres, pas les événements).


1 commentaires

Dans les exemples que j'ai examiné chaque source individuelle a brisé XML et toutes de différentes manières! Les autres erreurs courantes sont la casage des balises d'ouverture et de fermeture non correspondantes. Il serait difficile de travailler autour de chacun d'eux, de manière fiable au moins. Pour la remettre à la fois, la réparation des sources n'est pas une option - nous devons les soutenir comme le fournisseur précédent!



0
votes

envisager d'utiliser xml.sax . Quand je suis présenté XML vraiment malformé qui peut avoir une pléthore de problèmes différents, essayez de diviser le problème en petits morceaux.

Vous avez mentionné que vous avez un très grand fichier XML, il possède probablement de nombreux enregistrements que vous traitez en série. Et chaque enregistrement (E.G. <élément> ... a une étiquette de début et de fin, probablement - ces points de récupération vont-ils.

dans xml.sax Vous fournissez le lecteur, le gestionnaire et les sources d'entrée . A pire un seul enregistrement ne sera pas recouvert avec cette technique. C'est un peu plus de configuration, mais d'une analyse incrémentielle d'une alimentation mal formée, un enregistrement à une journalisation temporelle des mauvais enregistrements est probablement le meilleur que vous puissiez faire.

Dans les journaux, assurez-vous de vous donner suffisamment d'informations pour reconstruire l'enregistrement d'origine afin que vous puissiez ajouter du code de récupération supplémentaire pour tous les cas que vous devez ne pas avoir à gérer (par exemple, créer une date de badrecords_ date d'aujourd'hui .xml afin que vous puissiez se reproduire manuellement).

bonne chance.


0 commentaires

0
votes

ou, vous pouvez utiliser beauxoup . Cela fait un bon travail de récupération de ml brisé.


1 commentaires

Beautifulsoup est basé sur Dom, chargez donc tout le document en mémoire, ce qui ne répond pas aux exigences. Il est également assez lent pour tout ce qui est important, des exigences de mémoire de côté.