【问题标题】:ElementTree namespace dictionary not working with find() or findall()ElementTree 命名空间字典不适用于 find() 或 findall()
【发布时间】:2023-04-01 06:32:02
【问题描述】:

我对如何使用 documented sytnax 执行 ElementTree 命名空间字典以及随后的 find() 和 findall() 调用感到困惑:

搜索命名空间 XML 示例的更好方法是创建一个 带有您自己的前缀的字典并在搜索中使用这些前缀 功能:

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() 中的第二个参数传递,我会得到一个空列表。如果我在没有传递第二个参数的情况下输入完整的命名空间,它会返回所有预期的元素。

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

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>]

这会在我的示例文件中返回预期的 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 个&lt;ws:Worker&gt; 元素,其下有许多子子元素。

我搞这个的时间比我愿意承认的要长。我觉得我错过了一些非常明显的东西,在我看来,我的代码看起来就像我在网上找到的每个示例以及文档上的示例代码。

请帮忙!

【问题讨论】:

    标签: python xml elementtree xml-namespaces


    【解决方案1】:

    从 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>]
    

    【讨论】:

    • 你摇滚!这解决了它。我知道这将是一件很明显的事情,我会觉得自己很愚蠢。谢谢你帮助我!我使用通配符选项作为解决方法来继续开发和测试,直到我弄清楚命名空间部分。非常感谢!
    • +1 用于提供删除 {} 的重要信息 - 甚至更多用于指出 {*} 通配符!太棒了,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多