<p>这是你的程序的一个修改版本,我希望有意义。它演示了一个调用所有<code>TestHandler</code>方法的情况。在</p>
<pre><code>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: &num;'>Entity: &not;</test>
"""
main(XML)
</code></pre>
<p><strong>测试.dtd</strong>包含:</p>
^{pr2}$
<p>输出:</p>
<pre><code>TestHandler.resolveEntity(): None test.dtd
TestHandler.unparsedEntityDecl(): None bar.gif
TestHandler.startElement(): step: FOO
TestHandler.skippedEntity(): not
</code></pre>
<p><strong>添加</strong></p>
<p>据我所知,只有在使用外部DTD时才会调用<code>skippedEntity</code>(至少我不能想出反例;如果{a1}再清楚一点就好了)。在</p>
<p>Adam在他的回答中说,<code>resolveEntity</code>只对外部dtd调用。但事实并非如此。^当处理对在内部或外部DTD子集中声明的外部实体的引用时,也会调用{<cd3>}。例如:</p>
<pre><code><!DOCTYPE test [
<!ENTITY num SYSTEM "bar.txt">
]>
</code></pre>
<p>其中<strong>的内容条形图.txt</strong>可以是<code>FOO</code>。在本例中<a href="http://www.xml.com/axml/target.html#forbidden" rel="nofollow">it is not possible to refer to the entity in an attribute value</a>。在</p>