Python + Expat: Errore su & # 0; entità
-
27-09-2019 - |
Domanda
Ho scritto una piccola funzione, che utilizza ElementTree e XPath per estrarre il contenuto del testo di alcuni elementi in un file 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)
La terza prova non riesce con il seguente eccezione:
ExpatError: riferimento al numero di carattere non valido: riga 1, colonna 13
è l'entità �
XML illegale? Indipendentemente se si tratta o no, i file che voglio analizzare lo contengono, e ho bisogno di un modo per analizzare loro. Eventuali suggerimenti per un altro parser di Expat, o le impostazioni per Expat, che mi avrebbe permesso di farlo?
Aggiornamento: Ho scoperto BeautifulSoup solo ora, un parser tag zuppa come indicato di seguito nel risposta commento, e per divertimento sono andato di nuovo a questo problema e ha cercato di usarlo come un XML-pulitore di fronte elementtree, ma doverosamente ha convertito il �
in un just-in-validi nulla di byte. : -)
cleaned_s = StringIO(
BeautifulStoneSoup('<test><null>�</null><elem3>three</elem3></test>',
convertEntities=BeautifulStoneSoup.XML_ENTITIES
).renderContents()
)
tree = ElementTree.parse(cleaned_s)
... rendimenti
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 12
Nel mio caso particolare, però, non ho davvero bisogno il parsing XPath come tale, ho potuto andare con BeautifulSoup se stessa e il suo nodo abbastanza semplice rivolgendosi parsed_tree.test.elem1.contents[0]
stile.
Soluzione
�
non è nella gamma carattere legale definito dalle specifiche XML . Ahimè, le mie capacità Python sono piuttosto rudimentali, quindi non sono molto aiuto lì.
Altri suggerimenti
�
non è un carattere XML valido. Idealmente, si sarebbe in grado di ottenere il creatore del file per cambiare il loro processo in modo che il file non era valido come questo.
Se è necessario accettare questi file, si potrebbe loro pre-trattamento per trasformare �
in qualcos'altro. Ad esempio, selezionare @ come carattere di escape, girare "@" in "@@", e "�
" in "@ 0".
Quindi, come si ottiene i dati di testo dal parser, è possibile invertire la mappatura. Questo è solo un esempio, si può inventare qualsiasi sintassi fuggire ti piace.