如何使用名称空间遍历Elementtree

时间:2018-10-04 19:37:43

标签: python xml parsing elementtree

我一直试图使用python中的ElementTree来解析xml文档,以修改元素之一,但是由于名称空间,我一直遇到问题。

我可以使用

从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 :(得分:0)

如@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