Исправить неверный XML с амперсандами в Python

Я использую Python для манипулирования файлом XML, полученным из другой системы. Эта система производит недопустимый XML. В основном, это не исключает некоторые из & в XML.
Так, например, у меня есть такие строки:

<IceCream>Ben&Jerry</IceCream>


Конечно, когда анализируется с SAX или DOM, он выдает неверную ошибку токена.
Для более общего фона - это очень большой файл (2 МБ), довольно плоский и содержит много данных в CDATA.

Что я пробовал:

  1. Написание регулярного выражения для замены только unesacped &, без reesacaping & gt; и тому подобное: &(?!\w{2,4};), Это исправило это, но оно избежало амперсандов в CDATA, что затем вызвало ошибки в системе назначения. Я не могу потом удалить все, что находится в CDATA, потому что некоторые из них должны остаться без экранирования.
  2. Используя Красивый (Каменный) Суп. Тоже не повезло. Вместо того, чтобы избегать свободных амперсандов, он создал сущность (т.е. &Jerry;). Нехорошо.

Следующим шагом будет написание моего собственного парсера с использованием конечного автомата. Спаси меня от перехода по этой дороге.
Это не сложная структура (очень плоская, максимум 4 слоя), поэтому, возможно, регулярное выражение сможет отследить области, не входящие в CDATA.

Большое спасибо.

1 ответ

Решение

Используйте привязки Python для tidylib:

>>> import tidylib
>>> print tidylib.tidy_document("<IceCream>Ben&Jerry</IceCream>", {"input_xml": True})[0]
<IceCream>Ben&amp;Jerry</IceCream>

Смотрите официальную документацию для получения списка опций парсера.

Другие вопросы по тегам