Python: анализ XML-документа с сохранением сущностей - PullRequest
3 голосов
/ 17 августа 2010

Я хотел спросить, какие известные существующие библиотеки Python 2.x существуют для анализа XML-документа со встроенным DTD без автоматического расширения сущностей. (Файл для тех, кому интересно: JMdict .)

Кажется, в lxml есть какая-то опция, позволяющая не анализировать сущности, но в последний раз, когда я пытался, сущности просто оказались преобразованными в пробелы. Я просто погуглил и нашел pxdom в качестве другой альтернативы, которую я могу попробовать, но, поскольку это чистый Python, он кажется намного медленнее, чем хотелось бы.

Что-нибудь еще есть?

Ответы [ 4 ]

3 голосов
/ 20 февраля 2013

lxml упоминается в вопросе, и он делает то, что вы хотите, насколько я могу судить. Тестовый код:

from lxml import etree

XML = """
<!DOCTYPE root [
<!ENTITY abc "123">
]>
<root>
&abc;
</root>"""

parser = etree.XMLParser(resolve_entities=False)

root = etree.fromstring(XML, parser)
print "Entity not resolved:"
print etree.tostring(root)
print

print "Entity resolved:"
root = etree.fromstring(XML)
print etree.tostring(root)

Выход:

Entity not resolved:
<root>
&abc;
</root>

Entity resolved:
<root>
123
</root>
1 голос
/ 20 августа 2010

Для одного BeautifulStoneSoup из BeautifulSoup не будет расширять сущности по умолчанию.

Вероятно, он не будет быстрым или эффективным для вашего варианта использования, поскольку он ориентирован на другой тип использования (обработка всех видов некорректных и поврежденных разметок).

1 голос
/ 19 августа 2010

Кажется, что случай использования довольно ненормальный; не расширяющиеся сущности, кажется, идут вразрез с тем, как парсеры обычно должны работать в соответствии со спецификацией XML.

Так что, я думаю, проще всего просто запутать это, возможно. Я вручную извлек теги через re.finditer и составил словарь сопоставлений. Отсюда, это просто вопрос сканирования проанализированного вывода и правильной работы для моего приложения. Я думаю, достаточно хорошо для моего случая использования.

0 голосов
/ 13 июня 2018

У меня была похожая проблема, чтобы решить.Мне нужно было прочитать файл TEI XML, содержащий объекты типа

&some_exotic_char;

, которые были объявлены в отдельном файле DTD.Задача состояла в том, чтобы добавить некоторый атрибут в определенные теги и записать измененный файл, сохраняя при этом специальные сущности и не портя макет XML.

BeautifulSoup работал хорошо, пока я не захотел снова выписать файл XML:

with open('outfile.xml','w') as outfile:
    outfile.write(soup.prettify())

Тогда бы не оставило бы сущности «как есть», но вместо этого расширило бы их до utf8-символов, что было не тем, что я хотел.Кроме того, он испортил оригинальный макет XML, независимо от метода prettify (без него это еще хуже).

Наконец, я сдался и наконец нашел хорошее решение, используя Perl и XML :: LibXML .С помощью метода

$parser->expand_entities(0);

сущности не будут расширены.И запись XML обратно в файл сохранит исходный макет без изменений.

use XML::LibXML;
my $parser = new XML::LibXML;
$parser->validation(0);
$parser->load_ext_dtd(1);
$parser->expand_entities(0);
my $doc  = $parser->parse_file('infile.xml');

... # do whatever you need to do

open my $out, '>', 'outfile.xml';
binmode $out;
print $out $doc->toString();
close $out;

Perl XML :: LibXML спас мне день.

...