如何使用命名空间遍历 Elementtree
How to iterate through Elementtree using namespaces
我一直在尝试使用 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() takes at most 2 arguments (3 given)
看来我只给出了两个参数而不是三个。使用命名空间正确遍历这些元素我做错了什么?
*编辑:这是我的全部查询-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>
正如@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
我一直在尝试使用 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() takes at most 2 arguments (3 given)
看来我只给出了两个参数而不是三个。使用命名空间正确遍历这些元素我做错了什么?
*编辑:这是我的全部查询-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>
正如@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