Вот модифицированная версия вашей программы, которая, я надеюсь, имеет смысл.Он демонстрирует случай, когда вызываются все TestHandler
методы.
import StringIO
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 = StringIO.StringIO(xml_string)
parser.parse(stream)
stream.close()
except xml.sax.SAXParseException, e:
print "*** PARSER 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.resolveEntity(): None test.dtd
TestHandler.unparsedEntityDecl(): None bar.gif
TestHandler.startElement(): step: FOO
TestHandler.skippedEntity(): not
Добавление
Насколько я могу судить, skippedEntity
вызывается только при использовании внешнего DTD (по крайней мере, я не могу придумать контрпример;было бы хорошо, если бы документация была немного понятнее).
Адам сказал в своем ответе, что resolveEntity
вызывается только для внешних DTD.Но это не совсем так.resolveEntity
также вызывается при обработке ссылки на внешний объект, который объявлен во внутреннем или внешнем подмножестве DTD.Например:
<!DOCTYPE test [
<!ENTITY num SYSTEM "bar.txt">
]>
, где содержимое bar.txt может быть, скажем, FOO
.В этом случае невозможно ссылаться на сущность в значении атрибута .