2012-10-26 6 views
10

Mi piacerebbe stampare la struttura ad albero di un etree (formato da un documento html) in modo differenziabile (significa che due etrees devono essere stampati in modo diverso).lxml (o lxml.html): struttura ad albero di stampa

Quello che intendo per struttura è la "forma" dell'albero, che in pratica significa tutti i tag ma nessun attributo e nessun contenuto di testo.

Qualche idea? C'è qualcosa in lxml per farlo?

In caso contrario, suppongo di dover scorrere l'intero albero e costruire una stringa da quella. Qualche idea su come rappresentare l'albero in modo compatto? (la funzione "compatta" è meno rilevante)

FYI non è destinato a essere esaminato, ma per essere memorizzato e sottoposto a hash per poter fare differenze tra diversi modelli html.

Grazie

+2

C'è qualcosa che il metodo '.tostring()' non sta facendo per te? – kindall

+0

Sì, scusate se non è chiaro: ciò che intendo per struttura dell'albero è fondamentalmente solo i tag, nessun testo, nessun attributo nè (aggiunto in questione) – lajarre

+1

Non penso che LXML abbia questa funzionalità integrata, quindi dovrai camminare sull'albero. –

risposta

9

Forse basta eseguire alcuni XSLT sul XML di origine per mettere a nudo tutto, ma i tag, è quindi abbastanza facile da usare etree.tostring per ottenere una stringa si potrebbe hash ...

from lxml import etree as ET 

def pp(e): 
    print ET.tostring(e, pretty_print=True) 
    print 

root = ET.XML("""\ 
<project id="8dce5d94-4273-47ef-8d1b-0c7882f91caa" kpf_version="4"> 
<livefolder id="8744bc67-1b9e-443d-ba9f-96e1d0007ba8" idref="707cd68a-33b5-4051-9e40-8ba686c2fdb8">Mooo</livefolder> 
<livefolder id="8744bc67-1b9e-443d-ba9f" idref="707cd68a-33b5-4051-9e40-8ba686c2fdb8" /> 
<preference-set idref="8dce5d94-4273-47ef-8d1b-0c7882f91caa"> 
    <boolean id="import_live">0</boolean> 
</preference-set> 
</project> 
""") 
pp(root) 


xslt = ET.XML("""\ 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="*"> 
    <xsl:copy> 
     <xsl:apply-templates select="*"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 
""") 
tr = ET.XSLT(xslt) 

doc2 = tr(root) 
root2 = doc2.getroot() 
pp(root2) 

dà tu l'output:

<project id="8dce5d94-4273-47ef-8d1b-0c7882f91caa" kpf_version="4"> 
    <livefolder id="8744bc67-1b9e-443d-ba9f-96e1d0007ba8" idref="707cd68a-33b5-4051-9e40-8ba686c2fdb8">Mooo</livefolder> 
    <livefolder id="8744bc67-1b9e-443d-ba9f" idref="707cd68a-33b5-4051-9e40-8ba686c2fdb8"/> 
    <preference-set idref="8dce5d94-4273-47ef-8d1b-0c7882f91caa"> 
    <boolean id="import_live">0</boolean> 
    </preference-set> 
</project> 

<project> 
    <livefolder/> 
    <livefolder/> 
    <preference-set> 
    <boolean/> 
    </preference-set> 
</project> 
+0

Precisamente non sapevo molto di XSLT e sembra essere il modo giusto e standard per fare ciò che voglio – lajarre

+0

Una volta preso l'abitudine, è davvero utile per qualsiasi cosa in cui inizi con molta struttura e vuoi trasformarlo in qualcosa di più gestibile. Ricorda che le regole predefinite sono le stesse di questo foglio di stile: http://pastebin.com/b3WHMjPx, quindi copia elementi e attributi, ma nient'altro. – spiralx

+1

Questo posto ha un ottimo tutorial e materiale di riferimento ancora migliore per tutto ciò che riguarda XML: http://zvon.org/comp/m/tutorial.html – spiralx