Получение EXPAT для использования .dtd для замены сущности в Python

StackOverflow https://stackoverflow.com/questions/2881991

Вопрос

Я пытаюсь прочитать в файле XML, который выглядит так

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE dblp SYSTEM "dblp.dtd">
<dblp>
<incollection>
<author>Jos&eacute; A. Blakeley</author>
</incollection>
</dblp>

Точка, которая создает проблему, выглядит

Jos&eacute; 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  "&#192;" >
]>

Но это на самом деле не решает проблему вообще.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top