2009-12-15 43 views
1

我需要一個經過驗證的帶DTD的DomTree(使用getElementById)。 驗證和解析工作,但DOM簡化版,正常工作:從Sax到DTD(python)

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。

有什麼想法?

回答

1

據我所知:SAX DTD事件不是由ContentHandler處理,而是由DTDHandler處理,這是您可以在sax解析器(XMLReader)上設置的屬性。這意味着如果不序列化並重新分析文檔,則無法執行此操作。

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

在另一方面:除非你真的需要一個minidom命名文件,你會更好只是與LXML樹住。 (你可以使用相當於xpath的getElementById,或者看看etree.XMLDTDIDetree.parseid

+0

嗯,我認爲你是對的。解析並不是真正的選擇。我搜索了一下etree,看起來在各個方面都比minidom好。謝謝! – 2009-12-16 06:49:50