2017-01-22 4 views
0

При использовании модуля xml.etree python, как я могу избежать специальных символов xml, таких как '>' и '<' для использования внутри тега? Должен ли я делать это вручную? Есть ли у etree метод или kwarg, которых я не хватает?Python xml.etree escaping

Рассмотрим:

In [1]: from xml.etree.ElementTree import Element, SubElement, tostring 

In [2]: root = Element('filter') 

In [3]: root.set('type', 'test') 

In [4]: for op in ['<', '>', '=']: 
    ...:  sub_elem = SubElement(root, op) 
    ...:  child = Element('a') 
    ...:  child.text = 'b' 
    ...:  sub_elem.append(child) 
    ...: 

In [5]: tostring(root) 
Out[5]: '<filter type="test"><<><a>b</a></<><>><a>b</a></>><=><a>b</a></=></filter>' 

Где я хотел бы видеть разделы как:

<&lt><a>b</a></&lt> 
+0

Почему вы не используете 'for op in ['<', '>', '=']:'? – furas

+0

'<<> b' очень странная разметка. Вы действительно этого хотите? Это не правильно сформированный XML, это точно. – mzjn

ответ

1

Where I would like to see sections like:

<&lt><a>b</a></&lt>

Это неформальный XML. Думаю, вы забыли точки с запятой, но добавление их не помогает. Ниже также плохо сформированным:

<&lt;><a>b</a></&lt;> 

В коде, вы пытаетесь создать элементы, называемые <, > и =. Это не сработает. Все перечисленные ниже запрещены в именах XML-элементов: <, >, =, &gt;, &lt;.

К сожалению, ElementTree немного рыхлый и позволяет создавать псевдо XML, например, как это (от вопроса):

<filter type="test"><<><a>b</a></<><>><a>b</a></>><=><a>b</a></=></f‌​ilter> 

Если вы использовали lxml.etree (см http://lxml.de) вместо xml.etree.ElementTree, вы было бы получено сообщение об ошибке: «ValueError: недопустимое имя тега u» < «».

1

< и > в XML not valid characters, и вместо этого следует заменить &lt; и &gt; соответственно.

Вы можете использовать регулярное выражение для замены символов, которые являются недопустимыми:

import re 

regexp = re.compile(r'<|>') # here we are making a regex to catch either the character '<' or '>' 
replacement_map = {'<': '&lt;', '>': '&gt;'} # a dict to map a character to the replacement value. 
regexp.sub(lambda match: replacement_map[match.group(0)], '<a>hello</a>') # do the replacement 

# output: '&lt;a&gt;hello&lt;/a&gt;' 

Хотя код немного больше involoved, это очень эффективный способ делать замены.

+0

Это хороший способ сделать замену. мой вопрос больше касался того, нужна ли ручная замена. я был в основном смущен, почему этэ не убежал для меня или, по крайней мере, раскрыл очевидный вариант, чтобы позволить этому побегу. – djh