Есть ли в SAX в Python индекс, который сообщает мне, где я нахожусь в файле XML? И как бы мне это узнать?

У меня есть конкретный и общий вопрос.

Предположим, я использую 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")

Вероятно, вы ищете docs.python.org/3/library/… ...

AKX 15.12.2020 13:00

Sax немного низкоуровневый для обработки XML, другие библиотеки могут избавить вас от пота, бесплатно построив вам XML-дерево.

MetallimaX 15.12.2020 13:04

«У меня есть конкретный и общий вопрос». Пожалуйста, задавайте по одному вопросу за раз.

mzjn 15.12.2020 13:28
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
156
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот версия вашего примера, которая также печатает строку и столбец соответствующего элемента.

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()
    )
)

Другие вопросы по теме