Python利用命名空间解析XML文档


Posted in Python onAugust 10, 2020

问题

你想解析某个XML文档,文档中使用了XML命名空间。

解决方案

考虑下面这个使用了命名空间的文档:

<?xml version="1.0" encoding="utf-8"?>
<top>
  <author>David Beazley</author>
  <content>
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <title>Hello World</title>
      </head>
      <body>
        <h1>Hello World!</h1>
      </body>
    </html>
  </content>
</top>

如果你解析这个文档并执行普通的查询,你会发现这个并不是那么容易,因为所有步骤都变得相当的繁琐。

>>> # Some queries that work
>>> doc.findtext('author')
'David Beazley'
>>> doc.find('content')
<Element 'content' at 0x100776ec0>
>>> # A query involving a namespace (doesn't work)
>>> doc.find('content/html')
>>> # Works if fully qualified
>>> doc.find('content/{http://www.w3.org/1999/xhtml}html')
<Element '{http://www.w3.org/1999/xhtml}html' at 0x1007767e0>
>>> # Doesn't work
>>> doc.findtext('content/{http://www.w3.org/1999/xhtml}html/head/title')
>>> # Fully qualified
>>> doc.findtext('content/{http://www.w3.org/1999/xhtml}html/'
... '{http://www.w3.org/1999/xhtml}head/{http://www.w3.org/1999/xhtml}title')
'Hello World'
>>>

你可以通过将命名空间处理逻辑包装为一个工具类来简化这个过程:

class XMLNamespaces:
  def __init__(self, **kwargs):
    self.namespaces = {}
    for name, uri in kwargs.items():
      self.register(name, uri)
  def register(self, name, uri):
    self.namespaces[name] = '{'+uri+'}'
  def __call__(self, path):
    return path.format_map(self.namespaces)

通过下面的方式使用这个类:

>>> ns = XMLNamespaces(html='http://www.w3.org/1999/xhtml')
>>> doc.find(ns('content/{html}html'))
<Element '{http://www.w3.org/1999/xhtml}html' at 0x1007767e0>
>>> doc.findtext(ns('content/{html}html/{html}head/{html}title'))
'Hello World'
>>>

讨论

解析含有命名空间的XML文档会比较繁琐。 上面的 XMLNamespaces 仅仅是允许你使用缩略名代替完整的URI将其变得稍微简洁一点。

很不幸的是,在基本的 ElementTree 解析中没有任何途径获取命名空间的信息。 但是,如果你使用 iterparse() 函数的话就可以获取更多关于命名空间处理范围的信息。例如:

>>> from xml.etree.ElementTree import iterparse
>>> for evt, elem in iterparse('ns2.xml', ('end', 'start-ns', 'end-ns')):
... print(evt, elem)
...
end <Element 'author' at 0x10110de10>
start-ns ('', 'http://www.w3.org/1999/xhtml')
end <Element '{http://www.w3.org/1999/xhtml}title' at 0x1011131b0>
end <Element '{http://www.w3.org/1999/xhtml}head' at 0x1011130a8>
end <Element '{http://www.w3.org/1999/xhtml}h1' at 0x101113310>
end <Element '{http://www.w3.org/1999/xhtml}body' at 0x101113260>
end <Element '{http://www.w3.org/1999/xhtml}html' at 0x10110df70>
end-ns None
end <Element 'content' at 0x10110de68>
end <Element 'top' at 0x10110dd60>
>>> elem # This is the topmost element
<Element 'top' at 0x10110dd60>
>>>

最后一点,如果你要处理的XML文本除了要使用到其他高级XML特性外,还要使用到命名空间, 建议你最好是使用 lxml 函数库来代替 ElementTree 。 例如,lxml 对利用DTD验证文档、更好的XPath支持和一些其他高级XML特性等都提供了更好的支持。 这一小节其实只是教你如何让XML解析稍微简单一点。

以上就是Python利用命名空间解析XML文档的详细内容,更多关于Python命名空间解析XML文档的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python实现基于权重的随机数2种方法
Apr 28 Python
简析Python的闭包和装饰器
Feb 26 Python
Python环境下安装使用异步任务队列包Celery的基础教程
May 07 Python
Python编程中装饰器的使用示例解析
Jun 20 Python
CentOS 7下Python 2.7升级至Python3.6.1的实战教程
Jul 06 Python
Python简单实现网页内容抓取功能示例
Jun 07 Python
Python实现多线程的两种方式分析
Aug 29 Python
详解python项目实战:模拟登陆CSDN
Apr 04 Python
Python编译为二进制so可执行文件实例
Dec 23 Python
Python txt文件如何转换成字典
Nov 03 Python
python中sys模块的介绍与实例
Apr 17 Python
用Python进行栅格数据的分区统计和批量提取
May 27 Python
Python如何定义有默认参数的函数
Aug 10 #Python
如何更换python默认编辑器的背景色
Aug 10 #Python
django前端页面下拉选择框默认值设置方式
Aug 09 #Python
解决Django响应JsonResponse返回json格式数据报错问题
Aug 09 #Python
django 获取字段最大值,最新的记录操作
Aug 09 #Python
在django中查询获取数据,get, filter,all(),values()操作
Aug 09 #Python
Python 使用双重循环打印图形菱形操作
Aug 09 #Python
You might like
CentOS下PHP安装Oracle扩展
2015/02/15 PHP
PHP rsa加密解密使用方法
2015/04/27 PHP
PHP输入流php://input实例讲解
2015/12/22 PHP
php中的单引号、双引号和转义字符详解
2017/02/16 PHP
如果文字过长,则将过长的部分变成省略号显示
2006/06/26 Javascript
用javascript实现自定义标签
2007/05/08 Javascript
jquery中的事件处理详细介绍
2013/06/24 Javascript
jquery禁止输入数字以外的字符的示例(纯数字验证码)
2014/04/10 Javascript
JS实现点击按钮自动增加一个单元格的方法
2015/03/09 Javascript
prototype.js常用函数详解
2016/06/18 Javascript
PHP获取当前页面完整URL的方法
2016/12/02 Javascript
JS+HTML5 FileReader对象用法示例
2017/04/07 Javascript
详解node服务器中打开html文件的两种方法
2017/09/18 Javascript
详解vuex 渐进式教程实例代码
2018/11/27 Javascript
JavaScript继承与聚合实例详解
2019/01/22 Javascript
layer弹出层自定义提交取消按钮的例子
2019/09/10 Javascript
详解使用mocha对webpack打包的项目进行&quot;冒烟测试&quot;的大致流程
2020/04/27 Javascript
原生js实现随机点名
2020/07/05 Javascript
Vue触发input选取文件点击事件操作
2020/08/07 Javascript
[00:44]TI7不朽珍藏III——军团指挥官不朽展示
2017/07/15 DOTA
浅谈python3.x pool.map()方法的实质
2019/01/16 Python
Python抖音快手代码舞(字符舞)的实现方法
2021/02/07 Python
通过一张图教会你CSS3倒影的实现
2017/09/26 HTML / CSS
如何设定的weblogic的热启动模式(开发模式)与产品发布模式
2012/09/08 面试题
几个人围成一圈的问题
2013/09/26 面试题
优秀毕业生事迹材料
2014/02/12 职场文书
教师求职自荐信
2014/03/09 职场文书
施工员岗位职责
2014/03/16 职场文书
见习报告的格式
2014/11/04 职场文书
车间质检员岗位职责
2015/04/08 职场文书
职工的安全责任书范文!
2019/07/02 职场文书
PostgreSQL将数据加载到buffer cache中操作方法
2021/04/16 PostgreSQL
Mysql数据库索引面试题(程序员基础技能)
2021/05/31 MySQL
Win10 和 Win11可以共存吗? win10/11产品生命周期/服务更新介绍
2021/11/21 数码科技
关于vue-router-link选择样式设置
2022/04/30 Vue.js
超越Nginx的Web服务器caddy优雅用法
2022/06/21 Servers