2009-10-10 8 views
25

J'utilise Python's xml.dom.minidom pour créer un document XML. (Structure logique -> chaîne XML, pas l'inverse.)Python: Echapper des chaînes pour une utilisation en XML

Comment puis-je faire échapper les chaînes que je fournis afin qu'ils ne pourront pas gâcher le XML?

+2

Tout sérialiseur DOM DOM échappe les données de caractères de manière appropriée lorsqu'il s'éteint ... c'est pour cela que la manipulation DOM est faite, pour vous éviter d'avoir à vous salir les mains avec le balisage. – bobince

Répondre

10

Voulez-vous dire que vous faites quelque chose comme ceci:

from xml.dom.minidom import Text, Element 

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

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

Ensuite, vous obtiendrez bien échappé chaîne 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

Quelque chose comme ça?

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

Juste ce que je cherchais. La plus grande partie de ma manipulation XML est faite en utilisant lxml et je me demande si l'importation (encore) d'un autre module XML serait trop polluée? Y a-t-il un équivalent en lxml? (Ne peut pas sembler en trouver un.) – Jens

+9

Cela ne gère pas l'échappement des guillemets. – e1i45

+1

>>> de xml.sax.saxutils importer quoteattr >>> quoteattr (« valeur contenant" un guillemet \ » et une apostrophe ') « "valeur contenant " un guillemet \ » et une apostrophe « – user1048839

3

Si vous ne voulez pas une autre importation de projet et vous déjà cgi, vous pouvez utiliser ceci:

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

Notez cependant que cette lisibilité de code souffre - vous devriez probablement le mettre dans une fonction pour mieux décrire votre intention: (et écrire des tests unitaires pour pendant que vous y êtes;)

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

xml.sax .saxutils ne pas échapper les caractères guillemets (")

voici donc un autre:

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

si vous regardez vers le haut xml.sax.saxutils alors que la chaîne ne remplace

+1

pourrait vouloir échapper aussi le caractère de citation unique, à savoir« – Petri

+0

mieux éviter d'utiliser le mot-clé 'str' que votre variable prénom. – twasbrillig

8

xml.sax.saxutils.escape n'échappe &, < et > par défaut, mais il fournit un paramètre entities pour échapper en plus d'autres cordes:

from xml.sax.saxutils import escape 

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

xml.sax.saxutils.escape utilise str.replace() en interne, de sorte que vous pouvez également ignorer l'importation et à écrire votre propre fonction, comme indiqué dans la réponse de MichealMoser.

Questions connexes