2012-05-12 7 views
5

Ist es möglich, mithilfe von lxml (oder der integrierten etree-Bibliothek) ein Objekt zu erstellen, das ein XML-Fragment darstellt, aber zwei (oder mehr) getrennte Bäume enthält (dh jeder Baum hat seinen eigenen Stamm, aber keinen gemeinsamen Vorgänger))lxml XML-Fragment ohne Root-Element erstellen?

Das heißt, ist es etwas, das die folgenden ohne die Schaffung ein weiteres Element darstellen könnten beide halten:

<tree id="A"><anotherelement/></tree> 
<tree id="B"><yetanotherelement/></tree> 

ich nichts in der lxml Dokumentation sehen, die das erlauben würde, und Stackoverflow scheint nichts direkt am Punkt haben.

Der Anwendungsfall hier ist, dass ich XML programmgesteuert erzeuge, und die Fragmente werden in einem Dokument für die Ausgabe zusammengestellt. Ich möchte ein Objekt, das ich nicht überlesen muss/Spezialfall, nur an die lxml-Methoden übergeben, als wäre es ein richtiger Baum.

(Ich bin mir bewusst, dass solche Fragmente nicht von selbst ein vollständiges und korrektes XML-Dokument sein würden; ich möchte die Zwischenprodukte vor dem Zusammenbau in einem solchen Dokument speichern).

+0

Wie wäre es nur mit einer Liste von lxml-Objekten? Das ist ziemlich genau das, was Sie haben ... – larsks

+0

@larks Richtig, aber dann muss ich Code schreiben, der das Vorhandensein einer Liste handhabt, anstatt ein Objekt des Typs zu übergeben, den die XML-API erwartet. Dazu gehört entweder eine spezielle Hülle in meinem Code oder immer eine Liste. Deshalb wäre es vorzuziehen. – Marcin

Antwort

4

ja, es ist eine solche Funktionalität in der lxml.html Paket, ist es fragment_fromstring oder fragments_fromstring genannt, aber in den meisten Fällen die HTML-Parser übernimmt auch xml ganz gut:

from lxml import etree, html 

xml = """ 
    <tree id="A"><anotherelement/></tree> 
    <tree id="B"><yetanotherelement/></tree> 
""" 

fragments = html.fragments_fromstring(xml) 

root = etree.Element("root") 
for f in fragments: 
    root.append(f) 

print etree.tostring(root, pretty_print=True) 

Ausgang:

<root> 
    <tree id="A"> 
    <anotherelement/> 
    </tree> 
    <tree id="B"> 
    <yetanotherelement/> 
    </tree> 
</root> 

Wenn Sie sich what's going on under the hood ansehen, ist es wahrscheinlich nicht allzu schwierig, dasselbe mit dem XML-Parser zu tun, wenn Sie mit dem anderen Ergebnis nicht zufrieden sind.

+0

Danke dafür. Ich möchte das Fragment eigentlich programmatisch erstellen, also werde ich unter die Haube schauen. – Marcin

+0

Ah, es gibt immer noch eine Liste zurück - ich hatte gehofft, dass es eine Möglichkeit geben würde, ein Objekt zu erstellen, das ich nicht überlesen muss/Spezialfall, einfach an die lxml-Methoden übergeben, als wäre es ein richtiger Baum. Ich werde diese Antwort in den nächsten Tagen annehmen, vorausgesetzt niemand kennt eine magische Methode. – Marcin

+0

+1 aber auf jeden Fall wichtig zu wissen, dass 'fragments_fromstring()' eine Liste zurückgibt und 'fragment_fromstring()' nur ein einzelnes Element enthält – JCotton