使用 ElementTree 将 xml 转换为字典

2023-12-21

我正在寻找使用 ElementTree 的 XML 到字典解析器,我已经找到了一些,但它们排除了属性,在我的例子中,我有很多属性。


以下 XML-to-Python-dict 片段解析实体以及以下属性这个 XML 到 JSON“规范” http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html:

from collections import defaultdict

def etree_to_dict(t):
    d = {t.tag: {} if t.attrib else None}
    children = list(t)
    if children:
        dd = defaultdict(list)
        for dc in map(etree_to_dict, children):
            for k, v in dc.items():
                dd[k].append(v)
        d = {t.tag: {k: v[0] if len(v) == 1 else v
                     for k, v in dd.items()}}
    if t.attrib:
        d[t.tag].update(('@' + k, v)
                        for k, v in t.attrib.items())
    if t.text:
        text = t.text.strip()
        if children or t.attrib:
            if text:
                d[t.tag]['#text'] = text
        else:
            d[t.tag] = text
    return d

它的用途是:

from xml.etree import cElementTree as ET
e = ET.XML('''
<root>
  <e />
  <e>text</e>
  <e name="value" />
  <e name="value">text</e>
  <e> <a>text</a> <b>text</b> </e>
  <e> <a>text</a> <a>text</a> </e>
  <e> text <a>text</a> </e>
</root>
''')

from pprint import pprint

d = etree_to_dict(e)

pprint(d)

此示例的输出(根据上面链接的“规范”)应该是:

{'root': {'e': [None,
                'text',
                {'@name': 'value'},
                {'#text': 'text', '@name': 'value'},
                {'a': 'text', 'b': 'text'},
                {'a': ['text', 'text']},
                {'#text': 'text', 'a': 'text'}]}}

不一定漂亮,但它是明确的,更简单的 XML 输入会导致更简单的 JSON。 :)


Update

如果你想做reverse,发出一个来自 JSON/dict 的 XML 字符串, 您可以使用:

try:
  basestring
except NameError:  # python3
  basestring = str

def dict_to_etree(d):
    def _to_etree(d, root):
        if not d:
            pass
        elif isinstance(d, str):
            root.text = d
        elif isinstance(d, dict):
            for k,v in d.items():
                assert isinstance(k, str)
                if k.startswith('#'):
                    assert k == '#text' and isinstance(v, str)
                    root.text = v
                elif k.startswith('@'):
                    assert isinstance(v, str)
                    root.set(k[1:], v)
                elif isinstance(v, list):
                    for e in v:
                        _to_etree(e, ET.SubElement(root, k))
                else:
                    _to_etree(v, ET.SubElement(root, k))
        else:
            assert d == 'invalid type', (type(d), d)
    assert isinstance(d, dict) and len(d) == 1
    tag, body = next(iter(d.items()))
    node = ET.Element(tag)
    _to_etree(body, node)
    return node

print(ET.tostring(dict_to_etree(d)))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 ElementTree 将 xml 转换为字典 的相关文章

随机推荐

  • 将字符串与 Java 中声明为 Final 的 == 进行比较

    我有一个关于 Java 中字符串的简单问题 下面的简单代码段只是连接两个字符串 然后将它们与 String str1 str String str2 ing String concat str1 str2 System out printl
  • Django:如何使用自定义模板制作表单?

    我有一个模型 class Setting models Model class Meta abstract True name models CharField max length 120 primary key True descrip
  • 如何从一张画布复制到另一张画布

    我想复制在一张画布上绘制的图像 details http developer android com reference android graphics Canvas html 进入另一个画布 通常讨论的使用位图的解决方案将不起作用 因为
  • Django ORM - 百分号代表类似

    在我的网站上 用户应该能够过滤数字 例如 123 321 这将匹配 666123 555 321111 或LIKE 123 321 默认情况下django的orm转义 sign https docs djangoproject com en
  • 等待多张图片加载

    我有多个图像要加载 并将它们放入一个数组中 在循环中 加载图像时我会增加计数器 当这个计数器等于我的图像的数组长度时 我想删除加载指示器 我不知道为什么 这不起作用 new Vue el app created let imageLoade
  • Angular 4 服务中的数据,传递给组件

    服务中有一些数据 当我在服务上的对象中有数据时 它工作得很好 但现在我已经连接了数据库连接 数据永远不会到达组件 我希望该服务订阅从数据库返回的数据并定义如下调用 public setPerson ac string void consol
  • 高请求场景下Java Threadpool vs. new Thread

    我有一些用于 REST 服务的旧 Java 代码 该服务对每个传入请求使用单独的线程 IE 主循环将在 socket accept 上循环并将套接字移交给 Runnable 然后 Runnable 将启动自己的后台线程并调用自身运行 这在一
  • 将执行文本/模板模板的结果分配给变量[重复]

    这个问题在这里已经有答案了 type Inventory struct Material string Count uint sweaters Inventory wool 17 tmpl err template New test Par
  • iPhone - 不同应用程序有相同的配置文件吗?

    您可以使用相同的配置文件为 App Store 编译 2 个不同的应用程序吗 我想不是 但只是想知道 我非常确定您不能在 App Store 提交的 appID 中使用通配符 您可以使用类似的方法构建和调试所有应用程序GK46RTKQ4V
  • 通过查询查找组中的最后一行-SQL Server

    我在 SQL Server 中有表 我想找到每组中的最后一行 我尝试使用以下查询 但它没有返回准确的结果 ID列是PK 其他列设置为NOT NULL select ID Name FROM select ID Name max ID ove
  • Rails distance_of_time_in_words 返回“en, about_x_hours”

    我遇到了一个奇怪的问题 希望有人知道问题是什么 使用 distance of time in words 以及 time ago in words 不会返回实际的时间距离 相反 它返回诸如 en about x hours 或 en x m
  • 如何使用 Xcode 4.2 使用 ios 4.2 基础 sdk?

    如何使用 Xcode 4 2 使用 ios 4 2 基础 sdk 我拥有一部 iPhone 4s 和一部装有 ios 4 2 的 iTouch 将 Xcode 升级到 4 2 以与我的 iPhone 4s 配合使用后 我无法再将 Xcode
  • 在 Amazon EC2 微实例中运行 Play 框架应用程序

    我有一个非常基本的玩法 应用程序只处理几个正常的 GET 和 POST 请求并与 MySQL 数据库对话 没什么花哨的 I ran play dist并将 zip 文件传输到我的 EC2 实例 解压后 进入bin文件夹并运行 myapp 我
  • 解析来自 http get 的多部分响应

    我正在开发两个应用程序之间的集成 应用程序 1 使用 HttpClient GetMethod 向应用程序 2 发出请求 应用程序 2 将返回嵌入文件的多部分响应 我认为这是一个简单的练习 但似乎找不到解析 HTTP GET 的多部分响应的
  • Ngrx Effects 规范抛出错误“未初始化测试调度程序”

    尝试使用现有的和最近迁移的 Angular 7 项目运行简单的效果测试 但我收到如下错误 错误 未初始化测试调度程序在 getTestScheduler node modules jasmine marbles es6 src schedu
  • android中如何实现下拉刷新?

    目前我正在开发一个片段 它只是一个带有框架布局的网络视图 问题是 我想做类似的事情下拉刷新 就像列表视图中常见的一些刷新功能一样 假设有一个refreshToDo 功能 我所需要的只是一个布局 当我拖动主体时 它会显示刷新标题 当标题达到一
  • 通过 PHP 显示数据库中的 Base64 图像

    我有这个数据库 其中包含图像作为字符串 这些字符串看起来像这样 data image jpeg base64 9j 4AAQSkZJRgABAQEAYABgAAD 我需要创建一个显示该图像的链接 喜欢something com id 27是
  • Geb 的一般问题(StaleElementReferenceException 和等待超时)

    根据 Geb之书 我开始绘制我们门户网站的网页 我更喜欢使用静态内容闭包块中定义的变量 然后在页面方法中访问它们 static content buttonSend input type submit nicetitle Senden de
  • 为什么有用于 socket()、connect()、send() 等的 WSA 挂件,但没有用于 closesocket() 的 WSA 挂件?

    我将尝试用几个例子来解释我的意思 套接字 gt WSASocket 连接 gt WSAConnect 发送 gt WSASend sendto gt WSASendTo recv gt WSARecv recvfrom gt WSARecv
  • 使用 ElementTree 将 xml 转换为字典

    我正在寻找使用 ElementTree 的 XML 到字典解析器 我已经找到了一些 但它们排除了属性 在我的例子中 我有很多属性 以下 XML to Python dict 片段解析实体以及以下属性这个 XML 到 JSON 规范 http