Возврат результата из итератора дерева XML - PullRequest
1 голос
/ 03 июня 2019

У меня есть дерево xml:

<root>
    <expression>
        <add>
            <number>1</number>
            <number>2</number>
            <number>3</number>
        </add>
    </expression>
</root>

Моя функция перебирает дерево, добавляя int дочернего текста. Конечный результат оператора print - это тот результат, который мне нужен, но как мне вернуть его из функции addleafnodes?

root = etree.XML(request.data['expression'])
results = 0

def addleafnodes(root, results):
    for child in root:
        if root.tag != "root" and root.tag != "expression":
            results += int(child.text)
        print(results)
        addleafnodes(child, results)

newresults = addleafnodes(root, results)

Ответы [ 2 ]

1 голос
/ 03 июня 2019

Вы передаете results вниз по рекурсии и увеличиваете, но никогда не возвращаете его обратно "вверх". Если results был объектом, и вы просто передавали ссылку, вы могли бы посмотреть на нее после корневого вызова addleafnodes.

Следующее вернет сумму обратно в рекурсию:

from xml.etree.ElementTree import XML

expr = """<root>
    <expression>
        <add>
            <number>1</number>
            <number>2</number>
            <number>3</number>
        </add>
    </expression>
</root>
"""
root = XML(expr)

def addleafnodes(root, results):
    for child in root:
        if root.tag != "root" and root.tag != "expression":
            results += int(child.text)
        results = addleafnodes(child, results)
    return results

newresults = addleafnodes(root, 0)
print(newresults)

Я думаю, что этот функциональный подход хорош, но вы также можете просто обновить глобальную переменную изнутри рекурсии (я удалил results = 0 из этого фрагмента).

Обратите внимание, я не уверен, что код нарушается более глубокими структурами выражений (например, вложенные добавления и т. Д.).

0 голосов
/ 03 июня 2019

Ваш вопрос помечен lxml.Если вы действительно используете lxml, вы можете использовать функцию sum() xpath для упрощения ...

from lxml import etree

expr = """<root>
    <expression>
        <add>
            <number>1</number>
            <number>2</number>
            <number>3</number>
        </add>
    </expression>
</root>
"""

root = etree.fromstring(expr)


def addleafnodes(elem):
    return int(elem.xpath("sum(.//add/number)"))


newresults = addleafnodes(root)
print(newresults)

Печатный вывод ...

6

Также см. Здесь для получения дополнительной информации о xpath в lxml .

...