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>&#0;</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é &#0; 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 &#0; docilement en juste comme invalide-octet nul. : -)

cleaned_s = StringIO(
  BeautifulStoneSoup('<test><null>&#0;</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.

Était-ce utile?

La solution

&#0; est pas dans la défini par la spécification XML . Hélas, mes compétences Python sont assez rudimentaires, donc je suis pas beaucoup d'aide là-bas.

Autres conseils

&#0; 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 &#0 autre chose. Par exemple, choisissez @ comme un caractère d'échappement, tourner "@" dans "@@" et "&#0;" 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top