2010-08-04 7 views
11

Ho un file XML che specifica una codifica e utilizzo UnicodeDammit per convertirlo in unicode (per motivi di archiviazione, non posso memorizzarlo come stringa). Più tardi lo passo a lxml ma si rifiuta di ignorare la codifica specificata nel file e di analizzarlo come Unicode, e solleva un'eccezione.Esiste un modo per forzare lxml ad analizzare le stringhe Unicode che specificano una codifica in un tag?

Come posso forzare lxml per analizzare il documento? Questo comportamento sembra troppo restrittivo.

risposta

3

sostanza, la soluzione è quella di fare:

if isinstance(mystring, unicode): 
    mystring = mystring.encode("utf-8") 

Scherzi a parte. Bel lavoro, lxml.

MODIFICA: Si scopre che, in questo caso, lxml rileva automaticamente la codifica in modo errato. Sembra che dovrò cercare e rimuovere manualmente "charset" e "encoding" dalla pagina.

15

Non è possibile analizzare dalle stringhe Unicode e avere una dichiarazione di codifica nella stringa. Quindi, o lo rendi una stringa codificata (dato che apparentemente non puoi memorizzarla come stringa, dovrai ricodificarla prima di eseguire l'analisi. Oppure serializzi l'albero come unicode con lxml: etree.tostring(tree, encoding=unicode), SENZA dichiarazione xml . si può facilmente analizzare ancora una volta il risultato con etree.fromunicode

vedere http://lxml.de/parsing.html#python-unicode-strings

Edit:. Se, a quanto pare, è già la stringa unicode, e non si può controllare il modo in cui è stato fatto dovrete codificare di nuovo, e di fornire il parser con la codifica è stato utilizzato:

utf8_parser = etree.XMLParser(encoding='utf-8') 

def parse_from_unicode(unicode_str): 
    s = unicode_str.encode('utf-8') 
    return etree.fromstring(s, parser=utf8_parser) 

Questo farà in modo che, qualunque cosa fosse all'interno della dichiarazione xml venga ignorata, perché il parser userà sempre utf-8.

+0

L'intero problema è che non riesco a ottenere un albero in primo luogo, se io potessi wouldn' Non ho problemi ... –

+0

@Stavros Korokithakis, etree è il modulo, non l'albero analizzato. –

+0

@Daniel Kluev: Sì, ma "albero" è un albero. –

0

La soluzione NON sta ricodificando la stringa. La dichiarazione di codifica all'interno della stringa può dire qualcosa di diverso da UTF8. Non ricodificare ciecamente in utf8 e aspettarti che funzioni sempre.

La soluzione è semplicemente rimuovere la dichiarazione di codifica. Hai già una stringa unicode a portata di mano, non è più necessaria!

# this is from lxml/apihelpers.pxi 
RE_XML_ENCODING = re.compile(
    ur'^(<\?xml[^>]+)\s+encoding\s*=\s*["\'][^"\']*["\'](\s*\?>|)', re.U) 

RE_XML_ENCODING.sub("", broken_xml_string, count=1) 

Il caso peggiore (dove non viene trovata alcuna dichiarazione di codifica XML) Tempo di complessità qui è O (n), che è piuttosto male (ma ancora meglio di codifica ciecamente al binario) quindi sono aperto a suggerimenti qui .

PS: Alcune analisi interessanti del problema di codifica XML:

default encoding for XML is UTF-8 or UTF-16?

How default is the default encoding (UTF-8) in the XML Declaration?

Problemi correlati