Как перебирать Elementtree, используя пространства имен - PullRequest
0 голосов
/ 04 октября 2018

Я пытался проанализировать XML-документ, используя ElementTree в python, чтобы изменить один из элементов, однако я продолжаю сталкиваться с проблемами из-за пространств имен.

Я могу получить все теги из моего XML-документа с помощью

data = open('query-user-by-name.xml').read()
root = ET.fromstring(data)
for item in root.iter():
    print(item.tag)

, что дает мне:

{http://prism.evolveum.com/xml/ns/public/query-3}query
{http://prism.evolveum.com/xml/ns/public/query-3}filter
{http://prism.evolveum.com/xml/ns/public/query-3}equal
{http://prism.evolveum.com/xml/ns/public/query-3}matching
{http://prism.evolveum.com/xml/ns/public/query-3}path
{http://prism.evolveum.com/xml/ns/public/query-3}value

Я создал словарь с пространством имен:

namespaces = {'ns':'http://prism.evolveum.com/xml/ns/public/query-3'}

но когда я пытаюсь найти искомый элемент с помощью

data = open('query-user-by-name.xml').read()
root = ET.fromstring(data)
for item in root.iter('ns:value', namespaces):
    print(item.tag)

, я получаю сообщение об ошибке:

TypeError: iter () принимает значениебольшинство 2 аргументов (3 дано)

Кажется, я привожу только два аргумента, а не три.Что я делаю не так, чтобы правильно перебрать эти элементы, используя пространство имен?

* Редактировать: Вот мой файл query-all-users.xml:

<query xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
        xmlns="http://prism.evolveum.com/xml/ns/public/query-3">
<filter>
        <equal>
        <matching>polyStringNorm</matching>
                <path>c:name</path>
                <value>lilpotter</value>
        </equal>
</filter>
</query>

1 Ответ

0 голосов
/ 04 октября 2018

Как рекомендует @gill Hamilton, вы должны использовать iterfind, но с выражением XPath, например: ".//ns:value".

Вот полный пример:

import xml.etree.ElementTree as ET

content = u"""\
<query xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
        xmlns="http://prism.evolveum.com/xml/ns/public/query-3">
<filter>
        <equal>
        <matching>polyStringNorm</matching>
                <path>c:name</path>
                <value>lilpotter</value>
        </equal>
</filter>
</query>"""

root = ET.fromstring(content)

NS = {'ns': 'http://prism.evolveum.com/xml/ns/public/query-3'}

for item in root.iterfind(".//ns:value", NS):
    print(item.tag)

# -> {http://prism.evolveum.com/xml/ns/public/query-3}value
...