Мне трудно понять, как связать собственный ResolveEntityHandler с парсером SAX. На ТА есть этот ответ . Но, к сожалению, я не могу воспроизвести результат там.
Когда я запускаю следующий код, который фактически скопирован из вышеупомянутого ответа, только что обновлен до Python 3,
import io
import xml.sax
from xml.sax.handler import ContentHandler
# Inheriting from EntityResolver and DTDHandler is not necessary
class TestHandler(ContentHandler):
# This method is only called for external entities. Must return a value.
def resolveEntity(self, publicID, systemID):
print ("TestHandler.resolveEntity(): %s %s" % (publicID, systemID))
return systemID
def skippedEntity(self, name):
print ("TestHandler.skippedEntity(): %s" % (name))
def unparsedEntityDecl(self, name, publicID, systemID, ndata):
print ("TestHandler.unparsedEntityDecl(): %s %s" % (publicID, systemID))
def startElement(self, name, attrs):
summary = attrs.get('summary', '')
print ('TestHandler.startElement():', summary)
def main(xml_string):
try:
parser = xml.sax.make_parser()
curHandler = TestHandler()
parser.setContentHandler(curHandler)
parser.setEntityResolver(curHandler)
parser.setDTDHandler(curHandler)
stream = io.StringIO(xml_string)
parser.parse(stream)
stream.close()
except xml.sax.SAXParseException as e:
print ("ERROR %s" % e)
XML = """<!DOCTYPE test SYSTEM "test.dtd">
<test summary='step: #'>Entity: ¬</test>
"""
main(XML)
и внешнего test.dtd
<!ENTITY num "FOO">
<!ENTITY pic SYSTEM 'bar.gif' NDATA gif>
Что я получил, это
TestHandler.startElement(): step:
TestHandler.skippedEntity(): not
Process finished with exit code 0
Итак, мои вопросы:
- почему
resolveEntity
никогда не звонили? - как связать ResolveEntityHandler с вашим парсером?