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中常用的各种数据库操作模块和连接实例
May 29 Python
python文件和目录操作函数小结
Jul 11 Python
使用IPython来操作Docker容器的入门指引
Apr 08 Python
python使用KNN算法手写体识别
Feb 01 Python
python2.x实现人民币转大写人民币
Jun 20 Python
深入浅析Python2.x和3.x版本的主要区别
Nov 30 Python
python中aioysql(异步操作MySQL)的方法
Apr 11 Python
django中使用POST方法获取POST数据
Aug 20 Python
Windows+Anaconda3+PyTorch+PyCharm的安装教程图文详解
Apr 03 Python
Python生成器传参数及返回值原理解析
Jul 22 Python
Python-openpyxl表格读取写入的案例详解
Nov 02 Python
Python中json.load()和json.loads()有哪些区别
Jun 07 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
php 论坛采集程序 模拟登陆,抓取页面 实现代码
2009/07/09 PHP
Windows7下PHP开发环境安装配置图文方法
2010/05/20 PHP
simplehtmldom Doc api帮助文档
2012/03/26 PHP
php mysql操作mysql_connect连接数据库实例详解
2016/12/26 PHP
PHP框架自动加载类文件原理详解
2017/06/06 PHP
asp.net和asp下ACCESS的参数化查询
2008/06/11 Javascript
js函数排序的实例代码
2013/07/01 Javascript
使用JavaScript修改浏览器URL地址栏的实现代码
2013/10/21 Javascript
在JS中如何调用JSP中的变量
2014/01/22 Javascript
js控制网页背景音乐播放与停止的方法
2015/02/06 Javascript
JS定义网页表单提交(submit)的方法
2015/03/20 Javascript
JavaScript中textRange对象使用方法小结
2015/03/24 Javascript
基于JavaScript实现生成名片、链接等二维码
2015/09/20 Javascript
详谈javascript异步编程
2016/02/21 Javascript
jQuery提示插件qTip2用法分析(支持ajax及多种样式)
2016/06/08 Javascript
jQuery中animate的几种用法与注意事项
2016/12/12 Javascript
vuejs绑定class和style样式
2017/04/11 Javascript
js自定义瀑布流布局插件
2017/05/16 Javascript
详解RequireJs官方使用教程
2017/10/31 Javascript
Node.js 进程平滑离场剖析小结
2019/01/24 Javascript
详细分析Node.js 多进程
2020/06/22 Javascript
vue使用svg文件补充-svg放大缩小操作(使用d3.js)
2020/09/22 Javascript
Vue路由权限控制解析
2020/11/09 Javascript
Python学习笔记之os模块使用总结
2014/11/03 Python
用Python实现web端用户登录和注册功能的教程
2015/04/30 Python
Python实现针对含中文字符串的截取功能示例
2017/09/22 Python
PyQt5通信机制 信号与槽详解
2019/08/07 Python
Python3 无重复字符的最长子串的实现
2019/10/08 Python
Python学习笔记之函数的参数和返回值的使用
2019/11/20 Python
python循环输出三角形图案的例子
2019/11/22 Python
python异常处理try except过程解析
2020/02/03 Python
利用Node实现HTML5离线存储的方法
2020/10/16 HTML / CSS
荷兰网上买鞋:MooieSchoenen.nl
2017/09/12 全球购物
药品质量检测应届生求职信
2013/11/14 职场文书
应届毕业生自我评价分享
2013/12/15 职场文书
幼儿园家长反馈意见
2015/06/03 职场文书