2012-05-12 10 views
5

È possibile utilizzare lxml (o la libreria etree integrata) per creare un oggetto che rappresenta un frammento di xml, ma contiene due (o più) alberi disgiunti (cioè ogni albero ha una propria radice separata, ma non condividono alcun antenato comune)?lxml Crea un frammento XML senza elementi radice?

Cioè, c'è qualcosa che potrebbe rappresentare il seguente senza creare un altro elemento per contenere ciascuno di essi:

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

non riesco a vedere nulla nella documentazione lxml che avrebbe permesso questo, e sembra StackOverflow non avere nulla direttamente sul punto.

Il caso d'uso è che sto generando xml a livello di codice e che i frammenti verranno assemblati in un unico documento per l'output. Mi piacerebbe un oggetto che non ho bisogno di iterare su/caso speciale, basta passare ai metodi lxml come se fosse un albero corretto.

(Sono consapevole che tali frammenti non sarebbero di per sé un documento xml completo e corretto, ma voglio memorizzare i prodotti intermedi prima dell'assemblaggio in tale documento).

+0

Cosa ne pensi di creare un elenco di oggetti lxml? Questo è più o meno quello che hai ... – larsks

+0

@larsks Giusto, ma poi ho bisogno di scrivere codice che gestisca la presenza di una lista, piuttosto che passare un oggetto del tipo che l'API xml si aspetta. Ciò comporta anche l'uso di un involucro speciale nel mio codice o la possibilità di tenere sempre una lista. Questo è il motivo per cui sarebbe preferibile. – Marcin

risposta

4

sì, c'è un tale funzionalità nel pacchetto lxml.html, si chiama fragment_fromstring o fragments_fromstring, ma nella maggior parte dei casi il parser HTML gestisce anche xml abbastanza bene:

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) 

uscita:

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

se si guarda a what's going on under the hood, probabilmente non sarebbe troppo difficile fare lo stesso usando il parser xml se non si è soddisfatti dell'altro risultato.

+0

Grazie per questo. In realtà voglio creare il frammento a livello di codice, quindi sbirro sotto il cofano. – Marcin

+0

Ah, restituisce ancora una lista - speravo che ci fosse un modo per creare un oggetto che non ho bisogno di iterare su/caso speciale, basta passare ai metodi lxml come se fosse un albero corretto. Accetterò questa risposta nei prossimi giorni, supponendo che nessun altro conosca qualche metodo magico. – Marcin

+0

+1 ma sicuramente importante sapere che 'fragments_fromstring()' restituisce una lista e 'fragment_fromstring()' solo eccetto un singolo elemento – JCotton

Problemi correlati