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函数局部变量用法实例分析
Aug 04 Python
利用Python开发实现简单的记事本
Nov 15 Python
学习Python selenium自动化网页抓取器
Jan 20 Python
TensorFlow实现卷积神经网络CNN
Mar 09 Python
PyQt5实现拖放功能
Apr 25 Python
Python基于win32ui模块创建弹出式菜单示例
May 09 Python
用Python一键搭建Http服务器的方法
Jun 01 Python
Python 忽略warning的输出方法
Oct 18 Python
CentOS 7 安装python3.7.1的方法及注意事项
Nov 01 Python
Pycharm创建项目时如何自动添加头部信息
Nov 14 Python
python next()和iter()函数原理解析
Feb 07 Python
python打开文件的方式有哪些
Jun 29 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
利用“多说”制作留言板、评论系统
2015/07/14 PHP
php获取今日开始时间和结束时间的方法
2017/02/27 PHP
php readfile()修改文件上传大小设置
2017/08/11 PHP
JS中彻底删除JSON对象组成的数组中的元素
2020/09/22 PHP
javascript中this做事件参数相关问题解答
2013/03/17 Javascript
js 字符串转换成数字的三种方法
2013/03/23 Javascript
jquery mobile的触控点击事件会多次触发问题的解决方法
2014/05/08 Javascript
使用iojs的jsdom库实现同步系统时间
2015/04/20 Javascript
jquery实现两个图片渐变切换效果的方法
2015/06/25 Javascript
基于JavaScript实现根据手机定位获取当前具体位置(X省X市X县X街道X号)
2015/12/29 Javascript
JS 通过系统时间限定动态添加 select option的实例代码
2016/06/09 Javascript
jQuery回到顶部的代码
2016/07/09 Javascript
javascript使用 concat 方法对数组进行合并的方法
2016/09/08 Javascript
JS去除重复并统计数量的实现方法
2016/12/15 Javascript
Angular 2父子组件之间共享服务通信的实现
2017/07/04 Javascript
在ES5与ES6环境下处理函数默认参数的实现方法
2018/05/13 Javascript
详解IOS微信上Vue单页面应用JSSDK签名失败解决方案
2018/11/14 Javascript
vue项目中将element-ui table表格写成组件的实现代码
2019/06/12 Javascript
小程序瀑布流组件实现翻页与图片懒加载
2020/05/19 Javascript
VUE 实现element upload上传图片到阿里云
2020/08/12 Javascript
vue打包静态资源后显示空白及static文件路径报错的解决
2020/09/02 Javascript
vue项目如何监听localStorage或sessionStorage的变化
2021/01/04 Vue.js
[03:30]DOTA2完美“圣”典精彩集锦
2016/12/27 DOTA
Python中使用MELIAE分析程序内存占用实例
2015/02/18 Python
Python读写文件方法总结
2015/06/09 Python
速记Python布尔值
2017/11/09 Python
python中ASCII码字符与int之间的转换方法
2018/07/09 Python
在python tkinter界面中添加按钮的实例
2020/03/04 Python
pandas中的ExcelWriter和ExcelFile的实现方法
2020/04/24 Python
金融专业毕业生推荐信
2013/11/26 职场文书
服务生自我鉴定
2014/01/22 职场文书
本科生导师推荐信范文
2014/05/18 职场文书
物业保安岗位职责
2014/07/02 职场文书
群众路线学习笔记范文
2014/11/06 职场文书
100句拼搏进取的名言警句,值得一读!
2019/10/07 职场文书
详解Spring Security如何在权限中使用通配符
2022/06/28 Java/Android