Python метапрограммирование для разбора XML - PullRequest
1 голос
/ 01 сентября 2010

Я пытаюсь создать простой синтаксический анализатор XML, в котором каждая отдельная XML-схема имеет свой собственный класс синтаксического анализатора, но я не могу понять, каков наилучший способ. По сути, я хотел бы сделать что-то вроде этого:

in = sys.stdin
xmldoc = minidom.parse(in).documentElement

xmlParser = xmldoc.nodeName
parser = xmlParser()
out = parser.parse(xmldoc)

Я также не совсем уверен, правильно ли я получил имя корня документа, но в этом-то и заключается идея: создать объект класса с именем, аналогичным корню документа, и использовать функцию parse () в этом классе для анализа и обрабатывать ввод.

Какой самый простой способ добиться этого? Я читал о самоанализе и шаблонах, но пока не смог понять это. Я делал то же самое с Java в прошлом и AFAIK, Ruby также делает это простым. Что такое питонский путь?

Ответы [ 2 ]

1 голос
/ 20 октября 2010

Как отметил Марк в своем комментарии, чтобы получить ссылку на класс, имя которого вы знаете во время выполнения, вы используете getattr.

doc = minidom.parse(sys.stdin)
# is equivalent to
doc = getattr(minidom, "parse")(sys.stdin)

Ниже приведена исправленная версия вашего псевдокода.

from xml.dom import minidom
import sys
import myParsers # a module containing your parsers

xmldoc = minidom.parse(sys.stdin).documentElement

myParserName = xmldoc.nodeName
myParserClass = getattr(myParsers, myParserName)
# create an instance of myParserClass by calling it with the documentElement
parser = myParserClass(xmldoc)
# do whatever you want with the instance of your parser class
output = parser.generateOutput()

getattr вернет AttributeError, если атрибут не существует, так что вы можете заключить вызов в попытку ... кроме или передать третий аргумент getattr, который будет возвращен, если атрибут не найден.

1 голос
/ 01 сентября 2010

Я думаю, что большинство программистов на Python просто использовали бы lxml для анализа своих xml.Если вы все еще хотите обернуть это в классах, то можете, но, как сказал Делнан в своем комментарии, немного неясно, что вы на самом деле имеете в виду.читая свой код, вы должны попытаться хотя бы приблизительно следовать PEP 8. Более важно, однако, что вам действительно не следует присваивать встроенные функции, такие как «in».

...