2009-10-10 10 views
25

Używam Pythona do stworzenia xml.dom.minidom, aby utworzyć dokument XML. (Struktura logiczna -> ciąg XML, a nie na odwrót).Python: Escaping stringi do użycia w XML

W jaki sposób mogę go uciec z podanych przeze mnie łańcuchów, aby nie mogły zepsuć kodu XML?

+2

Dowolny serializator XML DOM ucieka przed danymi znakowymi odpowiednio podczas ich wychodzenia ... do czego służy manipulacja DOM, aby zapobiec zabrudzeniu rąk za pomocą znaczników. – bobince

Odpowiedz

10

Czy to znaczy, że coś takiego:

from xml.dom.minidom import Text, Element 

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

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

Wtedy dostaniesz ładnie uniknął XML ciąg:

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

Coś takiego?

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

Właśnie tego szukałem. Większość mojej obsługi XML odbywa się przy użyciu lxml i zastanawiam się, czy import (jeszcze) innego modułu XML byłby zbyt zanieczyszczony? Czy istnieje odpowiednik w lxml? (Nie można go znaleźć.) – Jens

+9

To nie obsługuje usuwania cudzysłowów. – e1i45

+1

>>> z xml.sax.saxutils import quoteattr >>> quoteattr („wartość zawierającej" podwójnie cytat \”i apostrof ') „"wartość zawierającą " podwójnie cytat \” i apostrof „« – user1048839

3

Jeśli nie chcesz inny projekt i import już masz cgi, możesz użyć tego:

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

jednak pamiętać, że z tego kodu czytelność cierpi - powinieneś umieścić go w funkcji, aby lepiej opisać swój zamiar: (i pisać testy jednostkowe dla niego, gdy jesteś na to;)

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

xml.sax .saxutils nie ucieczka znaki cudzysłowu (")

Więc tutaj jest inny:

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

jeżeli obejrzysz go następnie xml.sax.saxutils nie tylko ciąg zastąpić

+1

chcieć również uciec pojedynczy znak cudzysłowu, czyli» – Petri

+0

najlepiej unikać słowa kluczowego' str' jako zmiennej Nazwa. – twasbrillig

8

xml.sax.saxutils.escape ucieka tylko &, < i > domyślnie, ale daje parametr entities dodatkowo uciec inne ciągi:

from xml.sax.saxutils import escape 

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

xml.sax.saxutils.escape wykorzystuje str.replace() wewnętrznie, więc można również pominąć importowanie i napisz własną funkcję, jak pokazano w odpowiedzi MichealMoser.