Python + Expat: Erreur sur & # 0; entités
-
27-09-2019 - |
Question
Je l'ai écrit une petite fonction, qui utilise ElementTree et XPath pour extraire le contenu du texte de certains éléments dans un fichier xml:
#!/usr/bin/env python2.5
import doctest
from xml.etree import ElementTree
from StringIO import StringIO
def parse_xml_etree(sin, xpath):
"""
Takes as input a stream containing XML and an XPath expression.
Applies the XPath expression to the XML and returns a generator
yielding the text contents of each element returned.
>>> parse_xml_etree(
... StringIO('<test><elem1>one</elem1><elem2>two</elem2></test>'),
... '//elem1').next()
'one'
>>> parse_xml_etree(
... StringIO('<test><elem1>one</elem1><elem2>two</elem2></test>'),
... '//elem2').next()
'two'
>>> parse_xml_etree(
... StringIO('<test><null>�</null><elem3>three</elem3></test>'),
... '//elem2').next()
'three'
"""
tree = ElementTree.parse(sin)
for element in tree.findall(xpath):
yield element.text
if __name__ == '__main__':
doctest.testmod(verbose=True)
Le troisième test échoue à l'exception suivante:
ExpatError: référence au numéro de caractère non valide: ligne 1, colonne 13
L'entité �
XML illégal? Peu importe que ce soit ou non, les fichiers que je veux Parse contiennent, et je besoin d'une certaine façon de les analyser. Toutes les suggestions pour un autre analyseur de Expat, ou les paramètres pour Expat, qui me permettront de le faire?
Mise à jour: j'ai découvert BeautifulSoup tout à l'heure, un analyseur de soupe tag comme indiqué ci-dessous dans la commentaire de réponse, et pour le plaisir, je suis retourné à ce problème et a essayé de l'utiliser comme XML propre devant elementTree, mais il a converti le �
docilement en juste comme invalide-octet nul. : -)
cleaned_s = StringIO(
BeautifulStoneSoup('<test><null>�</null><elem3>three</elem3></test>',
convertEntities=BeautifulStoneSoup.XML_ENTITIES
).renderContents()
)
tree = ElementTree.parse(cleaned_s)
... rendements
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 12
Dans mon cas cependant, je n'ai pas vraiment besoin de l'analyse syntaxique XPath en tant que tel, je aurais pu aller avec BeautifulSoup lui-même et son parsed_tree.test.elem1.contents[0]
style de noeud assez adressage simple.
Autres conseils
�
est pas un caractère XML valide. Idéalement, vous seriez en mesure d'obtenir le créateur du fichier à modifier leur processus afin que le fichier n'a pas été invalide comme celui-ci.
Si vous devez accepter ces fichiers, vous pouvez les prétraiter pour transformer �
autre chose. Par exemple, choisissez @ comme un caractère d'échappement, tourner "@" dans "@@" et "�
" dans "@ 0".
Alors que vous obtenez les données de texte à partir de l'analyseur, vous pouvez inverser la cartographie. Ceci est juste un exemple, vous pouvez inventer une syntaxe échapper vous aimez.