2009-10-10 8 views
25

Sto usando Python xml.dom.minidom per creare un documento XML. (Struttura logica -> stringa XML, non viceversa.)Python: escaping di stringhe da utilizzare in XML

Come faccio a fuggire dalle stringhe fornite in modo che non siano in grado di rovinare l'XML?

+2

Qualsiasi serializzatore DOM XML sfuggirà in modo appropriato ai dati dei caratteri man mano che esce ... ecco a cosa serve la manipolazione DOM, per evitare di sporcarsi le mani con il markup. – bobince

risposta

10

Vuoi dire che fai qualcosa di simile:

from xml.dom.minidom import Text, Element 

t = Text() 
e = Element('p') 

t.data = '<bar><a/><baz spam="eggs"> & blabla &entity;</>' 
e.appendChild(t) 

Poi si aprirà ben sfuggito stringa XML:

>>> e.toxml() 
'<p>&lt;bar&gt;&lt;a/&gt;&lt;baz spam=&quot;eggs&quot;&gt; &amp; blabla &amp;entity;&lt;/&gt;</p>' 
60

Qualcosa di simile?

>>> from xml.sax.saxutils import escape 
>>> escape("< & >") 
'&lt; &amp; &gt;' 
+1

Proprio quello che stavo cercando. La maggior parte della mia gestione XML viene eseguita usando lxml e mi chiedo se importare (ancora) un altro modulo XML sia troppo inquinato? Esiste un equivalente in lxml? (Non riesco a trovarne uno.) – Jens

+9

Questo non gestisce l'escaping delle virgolette. – e1i45

+1

>>> da xml.sax.saxutils importare quoteattr >>> quoteattr ('valore contenente "una doppia citazione \' e un apostrofo ') '" il valore che contiene " una doppia citazione \' e un apostrofo " ' – user1048839

3

Se non si desidera un altro importazione progetto e già cgi, è possibile utilizzare questo:

>>> import cgi 
>>> cgi.escape("< & >") 
'&lt; &amp; &gt;' 

Nota, tuttavia, che con questo codice la leggibilità soffre - si dovrebbe metterlo in una funzione per meglio descrivere la vostra intenzione: (e scrivere unit test per esso, mentre si è in esso;)

def xml_escape(s): 
    return cgi.escape(s) # escapes "<", ">" and "&" 
6

xml.sax .saxutils non sfugge caratteri virgolette (")

Così qui è un altro:

def escape(str): 
    str = str.replace("&", "&amp;") 
    str = str.replace("<", "&lt;") 
    str = str.replace(">", "&gt;") 
    str = str.replace("\"", "&quot;") 
    return str 

se si guarda in su allora xml.sax.saxutils solo fa stringa sostituire

+1

potrebbe desiderare di sfuggire anche il singolo carattere preventivo, vale a dire' – Petri

+0

meglio evitare di usare la parola chiave' str' come la variabile nome. – twasbrillig

8

xml.sax.saxutils.escape sfugge solo &, <, e > per impostazione predefinita, ma fornisce un parametro entities di fuggire in aggiunta altre stringhe:

from xml.sax.saxutils import escape 

def xmlescape(data): 
    return escape(data, entities={ 
     "'": "&apos;", 
     "\"": "&quot;" 
    }) 

xml.sax.saxutils.escape utilizza str.replace() internamente, in modo da poter anche saltare l'importazione e scrivere il propria funzione, come mostrato nella risposta di MichealMoser.