Python SAX Parser: resolEntity - PullRequest
       64

Python SAX Parser: resolEntity

1 голос
/ 23 октября 2019

Мне трудно понять, как связать собственный 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: &num;'>Entity: &not;</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

Итак, мои вопросы:

  1. почему resolveEntity никогда не звонили?
  2. как связать ResolveEntityHandler с вашим парсером?

1 Ответ

1 голос
/ 24 октября 2019

То, что вы видите, связано с изменением в Python 3.7.1 :

Изменено в версии 3.7.1: Анализатор SAXбольше не обрабатывает общие внешние объекты по умолчанию для повышения безопасности. Ранее парсер создавал сетевые соединения для извлечения удаленных файлов или загружал локальные файлы из файловой системы для DTD и сущностей. Эту функцию можно снова включить с помощью метода setFeature() для объекта синтаксического анализатора и аргумента feature_external_ges.

Чтобы получить то же поведение, что и в более ранних версиях, добавьте следующие строки:

from xml.sax.handler import feature_external_ges

и (в функции main)

parser.setFeature(feature_external_ges, True)
...