От Sax до Dom с DTD (python) - PullRequest
       38

От Sax до Dom с DTD (python)

1 голос
/ 15 декабря 2009

Мне нужно проверенное DomTree с DTD (для использования getElementById). Проверка и анализ работают, но DOM не работает должным образом:

from xml.dom import minidom 
from xml.dom.pulldom import SAX2DOM
from lxml import etree
import lxml.sax
from StringIO import StringIO

data_string = """\
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE foo [
<!ELEMENT foo (bar)*>
<!ELEMENT bar (#PCDATA)>
<!ATTLIST bar id ID #REQUIRED>]><foo><bar id="nr_0">text</bar></foo> 
"""

#parser, with vali. at parsing
etree_parser = etree.XMLParser(dtd_validation=True,attribute_defaults=True) 
#parse it
sax_tree = etree.parse(StringIO(data_string),etree_parser);
handler = SAX2DOM();
lxml.sax.saxify(sax_tree,handler);
domObject = handler.document;

print domObject.getElementById("nr_0");
#returns None

print minidom.parseString(data_string).getElementById("nr_0");
#returns <DOM Element: bar at 0x7f36b77dc0e0>

Похоже, SAX2DOM не передаст DTD домену. Я что-то забыл? Я читал, что невозможно загрузить DTD после сборки dom.

есть идеи?

1 Ответ

1 голос
/ 15 декабря 2009

Насколько я знаю: события SAX DTD обрабатываются не ContentHandler, а DTDHandler , который можно задать для синтаксического анализатора саксофона (XMLReader). Это означает, что вы не можете сделать это без сериализации и повторного анализа документа.

validated_string = etree.tostring(tree)
domDocument = minidom.parseString(validated_string)

С другой стороны: если вы действительно не нуждаетесь в документе минидома, вам лучше остаться с деревом lxml. (вы можете использовать xpath для эквивалента getElementById или взглянуть на etree.XMLDTDID и etree.parseid)

...