Сохранение экранированных символов при разборе Python XML - PullRequest
2 голосов
/ 28 октября 2010

Я пытаюсь написать скрипт на python, который принимает один или два XML-файла и выводит один или два новых файла на основе содержимого входных файлов. Я пытался написать этот скрипт с помощью модуля minidom. Тем не менее, входные файлы содержат несколько экземпляров escape-символа

& # Xa;

внутри атрибутов узла. К сожалению, в выходных файлах эти символы были преобразованы в разные символы, которые кажутся символами новой строки.

Например, строка во входном файле, такая как:

<Entry text="For English For Hearing Impaired&#xa;Press 3 on Keypad"

Будет выводиться как

<Entry text="For English For Hearing Impaired
Press 3 on Keypad"

Я читал, что это вызвано минидомом, так как он не позволяет экранировать символы в атрибутах xml (я думаю). Это правда? И, если да, то какой инструмент / метод лучше всего использовать для анализа xml-файла в документе python, манипулирования узлами и обмена ими с другими документами и вывода документов обратно в новые файлы?

Если это поможет, я также анализировал и сохранял эти файлы, используя кодировку utf-8. Я не знаю, является ли это частью проблемы или нет. Спасибо за любую помощь, которую может оказать любой.

-Алекс Кайзер

Ответы [ 3 ]

4 голосов
/ 28 октября 2010

Я не использовал стандартные xml-модули Python с момента обнаружения lxml .Он может делать все, что вы ищете.Например ...

input.xml:

<?xml version="1.0" encoding='utf-8'?>
<root>
  <Button3 yposition="250" fontsize="16" language1="For English For Hearing Impaired&#xa;Press 3 on Keypad" />
</root>

и:

>>> from lxml import etree
>>> with open('input.xml') as f:
...     root = etree.parse(f)
...
>>> buttons = root.xpath('//Button3')
>>> buttons
[<Element Button3 at 101071f18>]
>>> buttons[0]
<Element Button3 at 101071f18>
>>> buttons[0].attrib
{'yposition': '250', 'language1': 'For English For Hearing Impaired\nPress 3 on Keypad', 'fontsize': '16'}
>>> buttons[0].attrib['foo'] = 'bar'
>>> s = etree.tostring(root, xml_declaration=True, encoding='utf-8', pretty_print=True)
>>> print(s)
<?xml version='1.0' encoding='utf-8'?>
<root>
  <Button3 yposition="250" fontsize="16" language1="For English For Hearing Impaired&#10;Press 3 on Keypad" foo="bar"/>
</root>
>>> with open('output.xml','w') as f:
...     f.write(s)
>>>
0 голосов
/ 18 мая 2016

К сожалению, стандартный модуль xml не имеет возможности отключить экранирование. Поэтому для меня лучшим вариантом было escape it back, используя метод из ElementTree, который используется для этой цели самой xml (метод из sax.utils не экранирует \n):

text = ElementTree._escape_attrib(text, 'utf-8')

Текст в источнике xml:

Here is a test message&#10;With newline &amp; ampersand

Текст после «декодирования»:

Here is a test message
With newline & ampersand

Текст после "побега назад":

Here is a test message&#10;With newline &amp; ampersand
0 голосов
/ 28 октября 2010

&#xa; - это объект XML для символа 0x0a или символ новой строки. Парсер правильно анализирует XML и выдает указанные символы. Если вы хотите запретить или иным образом иметь дело с символами новой строки в атрибутах, вы можете делать с ними все, что захотите, после того, как парсер предоставит их вам.

...