Как разрешить внешние сущности с помощью xml.etree, например lxml.etree

У меня есть скрипт, который анализирует XML с помощью lxml.etree:

from lxml import etree

parser = etree.XMLParser(load_dtd=True, resolve_entities=True)
tree = etree.parse('main.xml', parser=parser)

я нуждаюсь load_dtd=True а также resolve_entities=True вести себя &emptyEntry; от globals.xml Решили:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE map SYSTEM "globals.xml" [
    <!ENTITY dirData "${DATADIR}"> 
]>
<map 
    xmlns:map="http://my.dummy.org/map"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsschemaLocation="http://my.dummy.org/map main.xsd"
>

  &emptyEntry; <!-- from globals.xml -->

  <entry><key>KEY</key><value>VALUE</value></entry>
  <entry><key>KEY</key><value>VALUE</value></entry>
</map>

с globals.xml

<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY emptyEntry "<entry></entry>">

Теперь хотелось бы перейти от нестандартного lxml к стандарту xml.etree, Но это не с моим файлом, потому что load_dtd=True а также resolve_entities=True не поддерживается xml.etree,

Есть xml.etree способ разрешения этих объектов?

2 ответа

Решение

lxml - это правильный инструмент для работы.

Но, если вы хотите использовать stdlib, будьте готовы к трудностям и взгляните на метод UseForeignDTD в XMLParser. Вот хороший (но хакерский) пример: поддержка Python ElementTree для анализа неизвестных сущностей XML?

Мой трюк заключается в использовании внешней программы xmllint

proc = subprocess.Popen(['xmllint','--noent',fname],stdout=subprocess.PIPE)
output = proc.communicate()[0]
tree = ElementTree.parse(StringIO.StringIO(output))
Другие вопросы по тегам