ElementTree 命名空间字典不适用于 find() 或 findall()

ElementTree namespace dictionary not working with find() or findall()

我对如何使用 documented sytnax:

执行 ElementTree 命名空间字典以及随后的 find() 和 findall() 调用感到困惑

A better way to search the namespaced XML example is to create a dictionary with your own prefixes and use those in the search functions:

ns = {'real_person': 'http://people.example.com',
  'role': 'http://characters.example.com'}

for actor in root.findall('real_person:actor', ns):
    name = actor.find('real_person:name', ns)
    print(name.text)
    for char in actor.findall('role:character', ns):
        print(' |-->', char.text)

我遇到的问题是,如果我尝试使用该文档中注明的语法,通过将“ns”字典作为 find() 或 findall() 中的第二个参数传递,我会得到一个空列表。如果我在不传递第二个参数的情况下键入完整的命名空间,它 returns 所有预期的元素。

我这样定义我的命名空间字典:

ns = {'ws':'{urn:com.workday/workersync}'}

这是 ElementTree 和根设置:

xmlparser = ET.parse(xmlfile)
xmlroot = xmlparser.getroot()

这是我尝试使用文档中提到的字典快捷语法时得到的结果:

>>> xmlroot.findall('ws:Worker', ns)
[]

只是一个空列表...如果在调用中键入名称空间,我会得到以下结果:

xmlroot.findall('{urn:com.workday/workersync}Worker')
[<Element '{urn:com.workday/workersync}Worker' at 0x03220A78>, <Element'{urn:com.workday/workersync}Worker' at 0x0322D8C0>]

我的示例文件中 returns 预期的 2 个元素。

这是我的示例文件顶部的样子,供参考:

<?xml version="1.0" encoding="UTF-8"?>
<ws:Worker_Sync xmlns:ws="urn:com.workday/workersync" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <ws:Header>
        <ws:Version>34.0</ws:Version>
        <ws:Prior_Entry_Time>2020-07-04T21:40:25.822-07:00</ws:Prior_Entry_Time>
        <ws:Current_Entry_Time>2020-07-04T22:03:47.458-07:00</ws:Current_Entry_Time>
        <ws:Prior_Effective_Time>2020-07-04T00:00:00.000-07:00</ws:Prior_Effective_Time>
        <ws:Current_Effective_Time>2020-07-05T00:00:00.000-07:00</ws:Current_Effective_Time>
        <ws:Full_File>true</ws:Full_File>
        <ws:Document_Retention_Policy>30</ws:Document_Retention_Policy>
        <ws:Worker_Count>2</ws:Worker_Count>
    </ws:Header>
    <ws:Worker>
         *<snipped rest of XML data>*

截取的 XML 数据包含 2 个 <ws:Worker> 元素,它们下面有许多子元素。

我已经弄乱了这个问题的时间比我愿意承认的要长。我觉得我遗漏了一些非常明显的东西,在我看来,我的代码看起来像我在网上找到的每个示例以及文档中的示例代码。

请帮忙!

从 URI 字符串中删除大括号。名称空间字典应如下所示:

ns = {'ws': 'urn:com.workday/workersync'}

另一种选择是对命名空间使用通配符。 find()findall() since Python 3.8:

支持
print(xmlroot.findall('{*}Worker'))

输出:

[<Element '{urn:com.workday/workersync}Worker' at 0x033E6AC8>]