2012-09-17 15 views
9

Podczas tworzenia pliku XML z etree Pythona, jeśli będziemy pisać do pliku pusty tag korzystając SubElement, otrzymuję:Python kontrola etree Format pusty tag

<MyTag /> 

Niestety, nasza biblioteka parsera XML używane w Fortran robi nie radzę sobie z tym, mimo że jest to poprawny tag. Musi to zobaczyć:

<MyTag></MyTag> 

Czy istnieje sposób na zmianę reguł formatowania lub coś w stylu, aby to działało?

Odpowiedz

10

Zastosowanie metody html wypisać dokument:

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

Zarówno write() method i tostring() function przemawia method słów kluczowych, pod warunkiem korzystania Python 2.7 lub w górę.

We wcześniejszych wersjach Pythona można zainstalować zewnętrzną bibliotekę ElementTree; Wersja 1.3 obsługuje to słowo kluczowe.

Tak, to brzmi trochę dziwnie, ale dane wyjściowe html w większości zawierają puste elementy jako znacznik początkowy i końcowy. Niektóre elementy nadal kończą się jako puste elementy tagów; konkretnie <link/>, <input/>, <br/> i tym podobne. Mimo to, bądź to albo zaktualizuj swój parser XML Fortranu, aby rzeczywiście przeanalizować XML zgodny ze standardami!

+0

Niestety, nie ma innego parsera Fortran XML do użycia, więc jest to nasza jedyna opcja. Dzięki! – tpg2114

+0

Czy istnieje szansa na zachowanie przypadku tagu? Wygląda na to, że rozróżnianie wielkości liter jest również problemem, a 'html' nie zachowuje przypadku ... – tpg2114

+0

@ tpg2114: nie, przepraszam. –

0

Jeśli sed dostępny, można rura wyjście skryptu Pythona do

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

Który będzie żadnych wystąpienie <Tag /> i zastąpienie go przez <Tag></Tag>

2

Dodawanie pustego text ma innej opcji :

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

Należy jednak pamiętać, że zmieni to nie tylko reprezentację, ale także strukturę dokumentu: tj. child_el.text będzie '' zamiast None.

Och, i jak powiedział Martijn, spróbuj użyć lepszych bibliotek.

0

Parafrazując kodu wersja ElementTree.py używam zawiera następujące składniki w _write metody:

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

sterować licznik programu stworzyłem następujące:

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

Potem ustawić node.text = true_empty_string na tych węzłach ElementTree, w których chcę utworzyć tag zamykający, a nie samozamykający.

Przez "sterowanie licznikiem programu" rozumiem skonstruowanie zbioru danych wejściowych - w tym przypadku obiektu o nieco dziwnym teście prawdy - do metody biblioteki tak, że wywołanie metody biblioteki przebiega przez jej wykres przepływu kontrolnego w sposób Chcę tego. To jest absurdalnie kruche: w nowej wersji biblioteki moje włamanie może się zepsuć - powinieneś traktować "moc" jako "prawie gwarantowaną". Ogólnie rzecz biorąc, nie przełamuj barier abstrakcji. Dla mnie to po prostu zadziałało.

3

Zostało to bezpośrednio rozwiązane w Pythonie 3.4. Od tego czasu metoda xml.etree.ElementTree.ElementTreewrite ma parametr short_empty_elements których:

kontroluje formatowanie elementów, które nie zawierają treści. Jeśli True (wartość domyślna), są emitowane jako pojedyncza zamknięta etykieta, w przeciwnym razie są emitowane jako para początkowych/końcowych znaczników.

Więcej szczegółów w xml.etree documentation.