跳转到主要内容

让处理XML感觉就像处理JSON一样

项目描述

xmltodict

xmltodict 是一个 Python 模块,使处理 XML 感觉就像处理 JSON,就像在这个 "规范" 中一样

Build Status

>>> print(json.dumps(xmltodict.parse("""
...  <mydocument has="an attribute">
...    <and>
...      <many>elements</many>
...      <many>more elements</many>
...    </and>
...    <plus a="complex">
...      element as well
...    </plus>
...  </mydocument>
...  """), indent=4))
{
    "mydocument": {
        "@has": "an attribute", 
        "and": {
            "many": [
                "elements", 
                "more elements"
            ]
        }, 
        "plus": {
            "@a": "complex", 
            "#text": "element as well"
        }
    }
}

命名空间支持

默认情况下,xmltodict 不进行 XML 命名空间处理(它只将命名空间声明视为常规节点属性),但通过传递 process_namespaces=True 将为您展开命名空间

>>> xml = """
... <root xmlns="http://defaultns.com/"
...       xmlns:a="http://a.com/"
...       xmlns:b="http://b.com/">
...   <x>1</x>
...   <a:y>2</a:y>
...   <b:z>3</b:z>
... </root>
... """
>>> xmltodict.parse(xml, process_namespaces=True) == {
...     'http://defaultns.com/:root': {
...         'http://defaultns.com/:x': '1',
...         'http://a.com/:y': '2',
...         'http://b.com/:z': '3',
...     }
... }
True

它还允许您将某些命名空间折叠为缩写前缀,或完全跳过它们

>>> namespaces = {
...     'http://defaultns.com/': None, # skip this namespace
...     'http://a.com/': 'ns_a', # collapse "http://a.com/" -> "ns_a"
... }
>>> xmltodict.parse(xml, process_namespaces=True, namespaces=namespaces) == {
...     'root': {
...         'x': '1',
...         'ns_a:y': '2',
...         'http://b.com/:z': '3',
...     },
... }
True

流式传输模式

xmltodict 非常快(基于 Expat)并且具有小内存占用,适合大型 XML 导出,如 Discogs维基百科

>>> def handle_artist(_, artist):
...     print(artist['name'])
...     return True
>>> 
>>> xmltodict.parse(GzipFile('discogs_artists.xml.gz'),
...     item_depth=2, item_callback=handle_artist)
A Perfect Circle
Fantômas
King Crimson
Chris Potter
...

它还可以从命令行使用,将对象管道传输到脚本

import sys, marshal
while True:
    _, article = marshal.load(sys.stdin)
    print(article['title'])
$ bunzip2 enwiki-pages-articles.xml.bz2 | xmltodict.py 2 | myscript.py
AccessibleComputing
Anarchism
AfghanistanHistory
AfghanistanGeography
AfghanistanPeople
AfghanistanCommunications
Autism
...

或者仅缓存字典,这样您就无需再次解析那个大 XML 文件。您只需这样做一次

$ bunzip2 enwiki-pages-articles.xml.bz2 | xmltodict.py 2 | gzip > enwiki.dicts.gz

然后您可以在需要它们的每个脚本中重用这些字典

$ gunzip enwiki.dicts.gz | script1.py
$ gunzip enwiki.dicts.gz | script2.py
...

往返

您还可以使用 unparse() 方法进行反向转换

>>> mydict = {
...     'response': {
...             'status': 'good',
...             'last_updated': '2014-02-16T23:10:12Z',
...     }
... }
>>> print(unparse(mydict, pretty=True))
<?xml version="1.0" encoding="utf-8"?>
<response>
	<status>good</status>
	<last_updated>2014-02-16T23:10:12Z</last_updated>
</response>

节点的文本值可以使用Python字典中的cdata_key键进行指定,而节点属性可以使用Python字典中的键名前缀attr_prefix进行指定。默认值attr_prefix@,默认值cdata_key#text

>>> import xmltodict
>>> 
>>> mydict = {
...     'text': {
...         '@color':'red',
...         '@stroke':'2',
...         '#text':'This is a test'
...     }
... }
>>> print(xmltodict.unparse(mydict, pretty=True))
<?xml version="1.0" encoding="utf-8"?>
<text stroke="2" color="red">This is a test</text>

在字典的键下指定的列表使用键作为每个项目的标签。但如果列表确实有父键,例如如果列表位于另一个列表内部,它将没有标签可以使用,并且项目将像下面示例中所示的那样转换为字符串。为了给嵌套列表添加标签,请使用如以下示例所示的expand_iter关键字参数来提供标签。请注意,使用expand_iter将中断往返。

>>> mydict = {
...     "line": {
...         "points": [
...             [1, 5],
...             [2, 6],
...         ]
...     }
... }
>>> print(xmltodict.unparse(mydict, pretty=True))
<?xml version="1.0" encoding="utf-8"?>
<line>
        <points>[1, 5]</points>
        <points>[2, 6]</points>
</line>
>>> print(xmltodict.unparse(mydict, pretty=True, expand_iter="coord"))
<?xml version="1.0" encoding="utf-8"?>
<line>
        <points>
                <coord>1</coord>
                <coord>5</coord>
        </points>
        <points>
                <coord>2</coord>
                <coord>6</coord>
        </points>
</line>

好吧,我怎样才能得到它?

使用pypi

你只需要

$ pip install xmltodict

基于RPM的发行版(Fedora、RHEL等)

有[xmltodict的官方Fedora软件包](https://apps.fedoraproject.org/packages/python-xmltodict)。

$ sudo yum install python-xmltodict

Arch Linux

有[xmltodict的官方Arch Linux软件包](https://www.archlinux.org/packages/community/any/python-xmltodict/)。

$ sudo pacman -S python-xmltodict

基于Debian的发行版(Debian、Ubuntu等)

有[xmltodict的官方Debian软件包](https://tracker.debian.org/pkg/python-xmltodict)。

$ sudo apt install python-xmltodict

FreeBSD

有[xmltodict的官方FreeBSD端口](https://svnweb.freebsd.org/ports/head/devel/py-xmltodict/)。

$ pkg install py36-xmltodict

openSUSE/SLE(SLE 15、Leap 15、Tumbleweed)

有[xmltodict的官方openSUSE软件包](https://software.opensuse.org/package/python-xmltodict)。

# Python2
$ zypper in python2-xmltodict

# Python3
$ zypper in python3-xmltodict

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装软件包的更多信息。

源分布

xmltodict-0.13.0.tar.gz (33.8 kB 查看哈希)

上传时间

构建分布

xmltodict-0.13.0-py2.py3-none-any.whl (10.0 kB 查看哈希)

上传时间 Python 2 Python 3

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面