У меня есть конкретный и общий вопрос.
Предположим, я использую SAX для работы с приведенным ниже XML, но на самом деле он занимает 17 МБ и намного сложнее. В коде нет ошибок, но из-за того, что он такой сложный и мне, вероятно, не стоило приближаться к SAX в первую очередь, я получаю досадную логическую ошибку — иногда он выводит значение, которое меня не интересует, иногда справедливо игнорируя его. Эта логическая ошибка — единственное, что мешает мне закончить проект. Я пытаюсь отладить код, но это очень расстраивает, потому что даже мой усеченный тестовый XML-файл содержит 42 000 строк.
Итак, мой конкретный вопрос заключается в том, как я могу увидеть, какая строка XML-файла запускает любой данный startElement. Есть ли у startElement или ContentHandler индекс или что-то, что говорит вам, где в файле он находится?
Мой общий вопрос: как я могу узнать, как это сделать для себя? Я могу покопаться в Google, и Stack Overflow — потрясающий ресурс, за который я очень благодарен, но если бы я мог самостоятельно исследовать атрибуты вещей, с которыми работаю, это было бы гораздо более удовлетворительным. Например, есть ли способ в моем коде получить список всех вещей, которые зависают от startElement или переменной или чего-то еще, на самом деле. Len() говорит мне, какой длины что-то, Type() говорит мне, какого это типа. Существуют ли другие полезные мета-команды, к которым я могу прибегнуть, когда не уверен, какая у меня проблема?
Я как бы ожидаю, что на меня будут кричать за то, что я задаю два вопроса в одном, но я вижу, как задать общий вопрос, не будучи слишком расплывчатым.
Кредит http://pyxml.sourceforge.net/topics/howto/node12.html за этот код.
<collection>
<comic title = "Sandman" number='62'>
<writer>Neil Gaiman</writer>
<penciller pages='1-9,18-24'>Glyn Dillon</penciller>
<penciller pages = "10-17">Charles Vess</penciller>
</comic>
</collection>
Я имею дело с XML с помощью следующего кода:
from xml.sax import saxutils
class FindIssue(saxutils.handler.ContentHandler):
def __init__(self, title, number):
self.search_title, self.search_number = title, number
def startElement(self, name, attrs):
# If it's not a comic element, ignore it
if name != 'comic': return
# Look for the title and number attributes (see text)
title = attrs.get('title', None)
number = attrs.get('number', None)
if (title == self.search_title and number == self.search_number):
print (title, '#' + str(number), 'found')
from xml.sax import make_parser
from xml.sax.handler import feature_namespaces
if __name__ == '__main__':
# Create a parser
parser = make_parser()
# Tell the parser we are not interested in XML namespaces
parser.setFeature(feature_namespaces, 0)
# Create the handler
dh = FindIssue('Sandman', '62')
# Tell the parser to use our handler
parser.setContentHandler(dh)
# Parse the input
parser.parse("test.xml")
Sax немного низкоуровневый для обработки XML, другие библиотеки могут избавить вас от пота, бесплатно построив вам XML-дерево.
«У меня есть конкретный и общий вопрос». Пожалуйста, задавайте по одному вопросу за раз.
Вот версия вашего примера, которая также печатает строку и столбец соответствующего элемента.
import io
from xml.sax import saxutils
from xml.sax import make_parser
from xml.sax.handler import feature_namespaces
class FindIssue(saxutils.handler.ContentHandler):
def __init__(self, title, number):
self.locator = None
self.search_title = title
self.search_number = number
def setDocumentLocator(self, loc):
self.locator = loc
def startElement(self, name, attrs):
if name != "comic":
return
title = attrs.get("title")
number = attrs.get("number")
if title == self.search_title and number == self.search_number:
if self.locator:
print("Line", self.locator.getLineNumber(), "column", self.locator.getColumnNumber())
print(title, "#" + str(number), "found")
# Create a parser
parser = make_parser()
parser.setFeature(feature_namespaces, 0)
issue_finder = FindIssue("Sandman", "62")
parser.setContentHandler(issue_finder)
parser.parse(
io.StringIO(
"""
<collection>
<comic title = "Sandman" number='62'>
<writer>Neil Gaiman</writer>
<penciller pages='1-9,18-24'>Glyn Dillon</penciller>
<penciller pages = "10-17">Charles Vess</penciller>
</comic>
</collection>
""".strip()
)
)
Вероятно, вы ищете docs.python.org/3/library/… ...