строка отчета Python / столбец происхождения узла XML - PullRequest
6 голосов
/ 25 января 2011

В настоящее время я использую xml.dom.minidom для анализа некоторых XML в python.После разбора я делаю некоторые отчеты о содержимом и хотел бы сообщить строку (и столбец), где начался тег в исходном XML-документе, но я не понимаю, как это возможно.

Я хотел бы придерживаться xml.dom / xml.dom.minidom, если это возможно, но если мне нужно использовать SAX-анализатор для получения информации о происхождении, я могу это сделать - идеально в этом случае будет использовать SAX для отслеживаниярасположение узла, но все равно получаю DOM для моей постобработки.

Есть предложения, как это сделать?Надеюсь, я просто что-то пропустил в документах, и это очень легко.

Ответы [ 2 ]

4 голосов
/ 27 февраля 2011

Путем обезьянькой обработки обработчика содержимого minidom я смог записать номер строки и столбца для каждого узла (как атрибут 'parse_position'). Это немного грязно, но я не вижу никакого «официально санкционированного» способа сделать это :) Вот мой тестовый скрипт:

from xml.dom import minidom
import xml.sax

doc = """\
<File>
  <name>Name</name>
  <pos>./</pos>
</File>
"""


def set_content_handler(dom_handler):
    def startElementNS(name, tagName, attrs):
        orig_start_cb(name, tagName, attrs)
        cur_elem = dom_handler.elementStack[-1]
        cur_elem.parse_position = (
            parser._parser.CurrentLineNumber,
            parser._parser.CurrentColumnNumber
        )

    orig_start_cb = dom_handler.startElementNS
    dom_handler.startElementNS = startElementNS
    orig_set_content_handler(dom_handler)

parser = xml.sax.make_parser()
orig_set_content_handler = parser.setContentHandler
parser.setContentHandler = set_content_handler

dom = minidom.parseString(doc, parser)
pos = dom.firstChild.parse_position
print("Parent: '{0}' at {1}:{2}".format(
    dom.firstChild.localName, pos[0], pos[1]))
for child in dom.firstChild.childNodes:
    if child.localName is None:
        continue
    pos = child.parse_position
    print "Child: '{0}' at {1}:{2}".format(child.localName, pos[0], pos[1])

Выводит следующее:

Parent: 'File' at 1:0
Child: 'name' at 2:2
Child: 'pos' at 3:2
1 голос
/ 08 декабря 2014

Другим способом решения проблемы является исправление информации о номере строки в документе перед его анализом.Идея вот в чем:Номера столбцов тоже исправляются, что будет несколько сложнее.Кроме того, если вы хотите извлечь текстовые узлы или комментарии или использовать Node.toXml(), вы должны будете убрать LINE_DUMMY_ATTR из любых случайных совпадений, там.является то, что это не требует возиться с внутренностями minidom.

...