Самый быстрый / лучший способ прохождения XML с помощью lxml в Python - PullRequest
1 голос
/ 18 декабря 2011

У меня есть XML-файл, который выглядит так:

xml = '''<?xml version="1.0"?>
        <root>
            <item>text</item>
            <item2>more text</item2>
            <targetroot>
                <targetcontainer>
                    <target>text i want to get</target>
                </targetcontainer>
                <targetcontainer>
                    <target>text i want to get</target>
                </targetcontainer>
            </targetroot>
            ...more items
        </root>
'''

С помощью lxml я пытаюсь получить доступ к тексту в элементе . Я нашел решение, но я уверен, что есть лучший, более эффективный способ сделать это. Мое решение:

target = etree.XML(xml)

for x in target.getiterator('root'):
    item1 = x.findtext('item')
    for target in x.iterchildren('targetroot'):
        for t in target.iterchildren('targetcontainer'):
            targetText = t.findtext('target')

Хотя это работает, поскольку дает мне доступ ко всем элементам в корне, а также к целевому элементу, мне трудно поверить, что это самое эффективное решение.

Итак, мой вопрос заключается в следующем: есть ли более эффективный способ доступа к текстам , оставаясь в цикле root, потому что мне также нужен доступ к другим элементам.

1 Ответ

3 голосов
/ 18 декабря 2011

Вы можете использовать XPath :

for x in target.xpath('/root/targetroot/targetcontainer/target'):
    print x.text

Мы просим все элементы, которые соответствуют path .В этом случае путь равен /root/targetroot/targetcontainer/target, что означает

всех элементов <target>, которые находятся внутри элемента <targetcontainer>, внутри элемента <targetroot>, внутри элемента <root>,Кроме того, элемент <root> должен быть корнем документа, поскольку ему предшествует /, что означает начало документа.

Кроме того, в вашем XML-документе возникли две проблемы.Во-первых, объявление <?xml version="1.0"?> должно быть самым первым в документе - и в этом примере ему предшествует символ новой строки и пробел.Кроме того, это не тег и его не следует закрывать, поэтому </xml> в конце вашей строки следует удалить.В любом случае, я уже редактировал ваш вопрос.

EDIT : это решение еще можно улучшить.Вам не нужно проходить весь путь - вы можете просто спросить все элементы <target> внутри документа.Для этого перед именем тега ставится две косые черты.Поскольку вы хотите все тексты <target>, независимо от того, где они находятся, это может быть лучшим решением.Итак, цикл выше можно записать так:

for x in target.xpath('//target'):
    print x.text

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

...