Получение EXPAT для использования .dtd для замены сущности в Python
-
04-10-2019 - |
Вопрос
Я пытаюсь прочитать в файле XML, который выглядит так
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE dblp SYSTEM "dblp.dtd">
<dblp>
<incollection>
<author>José A. Blakeley</author>
</incollection>
</dblp>
Точка, которая создает проблему, выглядит
José A. Blakeley
Часть: анализатор дважды называет его обработчик персонажа один раз с «JOS», один раз с «А. Блакелей». Теперь я понимаю, что это может быть правильным поведением, если оно не знает, что Eaucute Entity. Однако это определяется в dblp.dtd, который у меня есть. Кажется, я не могу убедить Expat использовать этот файл, хотя. Все, что я могу сказать, это
p = xml.parsers.expat.ParserCreate()
# tried with and without following line
p.SetParamEntityParsing(xml.parsers.expat.XML_PARAM_ENTITY_PARSING_ALWAYS)
p.UseForeignDTD(True)
f = open(dblp_file, "r")
p.ParseFile(f)
Но Expat до сих пор не признает мою сущность. Почему нет способа сказать Expat, какой DTD использовать? я пробовал
- поместив файл в тот же каталог, что и XML
- поместив файл в рабочий каталог программы
- Замена ссылки в файл XML по абсолютному пути
Что мне не хватает? Спасибо.
Решение
Как я понимаю, если вы используете Pyexpat напрямую, вы должны предоставить свой собственный ExternalEntityRefHandler
Чтобы получить внешний DTD и подавать его в эксплуатацию.
Смотри, например, xml.sax.expatreader
Например, код (метод external_entity_ref
, Линия 374 в Python 2.6).
Вероятно, было бы лучше использовать интерфейс более высокого уровня, такой как SAX (через expatreader
) если вы можете.
Другие советы
Кстати, я могу временно помочь себе, скопировав соответствующие части .dtd в сам файл XML, как в
<!DOCTYPE dblp [
<!ENTITY Agrave "À" >
]>
Но это на самом деле не решает проблему вообще.