我需要一个带有DTD的经过验证的DomTree(使用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传递给dom。我忘记了什么吗? 我已经读过在构建dom之后无法加载DTD。
任何想法?
答案 0 :(得分:1)
据我所知:SAX DTD事件不是由ContentHandler处理的,而是由DTDHandler处理的,{{3}}是可以在sax解析器(XMLReader)上设置的属性。这意味着如果不对文档进行序列化和重新分析,则无法执行此操作。
validated_string = etree.tostring(tree)
domDocument = minidom.parseString(validated_string)
另一方面:除非你真的需要一个迷你文档,否则你最好还是继续使用lxml树。 (您可以使用xpath代替getElementById
,或者查看etree.XMLDTDID
和etree.parseid
)