2012-09-17 15 views
9

Quando si crea un file XML con eTree di Python, se scriviamo al file un tag vuoto utilizzando SubElement, ottengo:Python controllo eTree formato tag vuoto

<MyTag /> 

Purtroppo, la nostra biblioteca parser XML utilizzato in Fortran doesn gestirlo anche se è un tag corretto. Deve vedere:

C'è un modo per modificare le regole di formattazione o qualcosa in eterno per farlo funzionare?

risposta

10

Utilizzare il metodo html per scrivere il documento:

>>> from xml.etree import ElementTree as ET 
>>> ET.tostring(ET.fromstring('<mytag/>'), method='html') 
'<mytag></mytag>' 

Sia il write() method e la tostring() function sostenere l'argomento method parola chiave, a patto di utilizzare Python 2.7 o verso l'alto.

Nelle versioni precedenti di Python, è possibile installare la libreria ElementTree esterna; la versione 1.3 supporta quella parola chiave.

Sì, sembra un po 'strano, ma l'output html emette principalmente elementi vuoti come tag di inizio e fine. Alcuni elementi finiscono ancora come elementi tag vuoti; in particolare <link/>, <input/>, <br/> e così via. Ciò nonostante, o aggiorna il parser Fortran XML per analizzare effettivamente l'XML conforme agli standard!

+0

Sfortunatamente, non c'è altro parser Fortran XML da utilizzare, quindi questa è la nostra unica opzione. Grazie! – tpg2114

+0

Qualche possibilità esiste un modo per mantenere il caso del tag? Apparentemente anche la distinzione tra maiuscole e minuscole è un problema e 'html' non conserva il caso ... – tpg2114

+0

@ tpg2114: no, scusa. –

0

Se avete sed a disposizione, si potrebbe inviare l'output dello script python per

sed -e "s/<\([^>]*\) \/>/<\1><\/\1>/g" 

che troverà qualsiasi occorrenza di <Tag /> e sostituirlo con <Tag></Tag>

2

Aggiunta di un vuoto text è un'altra opzione :

etree.SubElement(parent, 'child_tag_name').text='' 

Ma si noti che questo cambierà non solo la rappresentazione ma anche la struttura del documento: ad esempio child_el.text sarà '' anziché None.

Oh, e come ha detto Martijn, cerca di usare librerie migliori.

0

Parafrasando il codice, la versione di ElementTree.py io uso contiene quanto segue in un metodo _write:

write('<' + tagname) 
... 
if node.text or len(node): # this line is literal 
    write('>') 
    ... 
    write('</%s>' % tagname) 
else: 
    write(' />') 

per guidare il contatore di programma che ho creato il seguente:

class AlwaysTrueString(str): 
    def __nonzero__(self): return True 
true_empty_string = AlwaysTrueString() 

Poi ho impostato node.text = true_empty_string su quei nodi ElementTree dove voglio un tag open-close piuttosto che un self-closing.

"governando il contatore del programma" intendo la costruzione di un insieme di input, in questo caso un oggetto con un test di verità piuttosto curioso, a un metodo di libreria tale che l'invocazione del metodo di libreria attraversa il suo diagramma di flusso di controllo nel modo Lo voglio Questo è ridicolmente fragile: in una nuova versione della libreria, il mio hack potrebbe rompersi, e probabilmente dovresti trattare "potrebbe" come "quasi garantito". In generale, non rompere le barriere di astrazione. Ha funzionato solo per me qui.

3

Questo è stato risolto direttamente in Python 3.4. Da allora, il metodo di xml.etree.ElementTree.ElementTreewrite ha il parametro short_empty_elements cui:

controlla la formattazione di elementi che non contengono contenuti. Se True (il valore predefinito), vengono emessi come un singolo tag auto-chiuso, altrimenti vengono emessi come una coppia di tag di inizio/fine.

Ulteriori dettagli nel numero xml.etree documentation.

Problemi correlati