Domanda

Sto cercando di creare XML utilizzando la struttura dell'oggetto ElementTree in python. Tutto funziona molto bene, tranne quando si tratta di istruzioni di elaborazione. Posso creare un PI facilmente utilizzando la funzione di fabbrica ProcessingInstruction (), ma non viene aggiunto nel elementtree. Posso aggiungere manualmente, ma non riesco a capire come inserirlo sopra dell'elemento radice dove PI del sono normalmente posizionati. Qualcuno sa come fare questo? Conosco un sacco di metodi alternativi di farlo, ma sembra che questo deve essere costruito in qualche parte che non riesco proprio a trovare.

È stato utile?

Soluzione

Prova biblioteca lxml: ne consegue l'API ElementTree, e aggiunge un sacco di extra. Dal compatibilità panoramica :

  

ElementTree ignora i commenti e le istruzioni di elaborazione durante l'analisi XML, mentre eTree li leggerà e trattarli come elementi commento o ProcessingInstruction rispettivamente. Ciò è particolarmente visibile in cui commenti si trovano all'interno il contenuto del testo, che viene poi diviso dall'elemento Commento.

     

È possibile disattivare questo comportamento passando i remove_comments e / o parole chiave remove_pis argomenti booleani al parser che si usa. Per comodità e per sostenere codice portabile, è anche possibile utilizzare la etree.ETCompatXMLParser al posto del etree.XMLParser default. Si cerca di fornire una configurazione di default che è il più vicino al parser ElementTree possibile.

Non nel stdlib, lo so, ma nella mia esperienza la cosa migliore da quando hai bisogno di cose che lo standard ElementTree non fornisce.

Altri suggerimenti

Con l'API lxml non potrebbe essere più facile, anche se è un po ' "underdocumented":

Se avete bisogno di un'istruzione di elaborazione di livello superiore, creare in questo modo:

from lxml import etree

root = etree.Element("anytagname")
root.addprevious(etree.ProcessingInstruction("anypi", "anypicontent"))

Il documento risultante sarà simile a questa:

<?anypi anypicontent?>
<anytagname />

Certamente dovrebbero aggiungere questo alla loro FAQ perché IMO è un'altra caratteristica che contraddistingue questo bene API a parte.

Si, non credo che sia possibile, mi dispiace. ElementTree fornisce un'interfaccia semplice per (non-namespace) incentrato sugli elementi di elaborazione XML di DOM, ma il prezzo di ciò è che non supporta l'intero infoset XML.

Non c'è modo evidente per rappresentare il contenuto che vive al di fuori del elemento radice (commenti, PI, il doctype e la dichiarazione XML), e questi sono anche scartati in fase di analisi. (A parte:. Questo sembra includere tutti gli attributi predefiniti specificati nel sottoinsieme interno DTD, il che rende ElementTree rigorosamente di lingua un processore XML non conforme)

Probabilmente si può lavorare intorno ad esso da sottoclassi o scimmia-patching metodo write() della realizzazione ElementTree nativo di Python a chiamare _write sui vostri inibitori della proteasi in più prima della _writeing _root, ma potrebbe essere un po 'fragile.

Se avete bisogno di supporto per la completa infoset XML, probabilmente meglio bastone con DOM.

Non so molto di ElementTree. Ma è possibile che si potrebbe essere in grado di risolvere il problema utilizzando una libreria ho scritto chiamato "xe".

XE è un insieme di classi Python progettato per rendere più semplice la creazione di XML strutturato. Non ho lavorato su di essa in un tempo lungo, per vari motivi, ma sarei disposto ad aiutarvi se avete domande su di esso, o hai bisogno di bug.

Ha le ossa nude di supporto per cose come le istruzioni di elaborazione, e con un po 'di lavoro penso che potrebbe fare quello che ti serve. (Quando ho iniziato l'aggiunta di istruzioni di elaborazione, non ho davvero capirli, e non ho avuto alcun bisogno di loro, in modo che il codice è una sorta di cotto a metà.)

Date un'occhiata e vedere se sembra utile.

http://home.avvanta.com/~steveha/xe.html

Ecco un esempio di utilizzo:

import xe
doc = xe.XMLDoc()

prefs = xe.NestElement("prefs")
prefs.user_name = xe.TextElement("user_name")
prefs.paper = xe.NestElement("paper")
prefs.paper.width = xe.IntElement("width")
prefs.paper.height = xe.IntElement("height")

doc.root_element = prefs


prefs.user_name = "John Doe"
prefs.paper.width = 8
prefs.paper.height = 10

c = xe.Comment("this is a comment")
doc.top.append(c)

Se è stato eseguito il codice qui sopra e poi corse print doc qui è quello che si otterrebbe:

<?xml version="1.0" encoding="utf-8"?>
<!-- this is a comment -->
<prefs>
    <user_name>John Doe</user_name>
    <paper>
        <width>8</width>
        <height>10</height>
    </paper>
</prefs>

Se siete interessati a questo, ma bisogno di aiuto, fammelo sapere.

Buona fortuna con il vostro progetto.

f = open('D:\Python\XML\test.xml', 'r+')
old = f.read()
f.seek(44,0)      #place cursor after xml declaration
f.write('<?xml-stylesheet type="text/xsl" href="C:\Stylesheets\expand.xsl"?>'+ old[44:])

stavo affrontando lo stesso problema e si avvicinò con questa soluzione grezza dopo aver fallito per inserire il PI nel file XML correttamente anche dopo aver utilizzato uno dei metodi Element nel mio caso root.insert (0, PI) e cercando diversi modi per tagliare e incollare il inserito PI alla posizione corretta solo per trovare i dati cancellati da luoghi inaspettati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top