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生成器实现微线程编程的教程
Apr 13 Python
centos6.7安装python2.7.11的具体方法
Jan 16 Python
使用python 和 lint 删除项目无用资源的方法
Dec 20 Python
TensorFlow卷积神经网络之使用训练好的模型识别猫狗图片
Mar 14 Python
PyQt5 实现给窗口设置背景图片的方法
Jun 13 Python
python基于Selenium的web自动化框架
Jul 14 Python
解决pytorch报错:AssertionError: Invalid device id的问题
Jan 10 Python
Python图像处理库PIL的ImageDraw模块介绍详解
Feb 26 Python
python实现井字棋小游戏
Mar 04 Python
解决导入django_filters不成功问题No module named 'django_filter'
Jul 15 Python
python3 使用ssh隧道连接mysql的操作
Dec 05 Python
Pandas数据结构之Series的使用
Mar 31 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 date函数参数详解
2006/11/27 PHP
漂亮的thinkphp 跳转页封装示例
2019/10/16 PHP
js实现网站首页图片滚动显示
2013/02/04 Javascript
js 弹出新页面避免被浏览器、ad拦截的一种新方法
2014/04/30 Javascript
javascript作用域问题实例分析
2015/07/13 Javascript
js实现TAB切换对应不同颜色的代码
2015/08/31 Javascript
JavaScript实现的伸展收缩型菜单代码
2015/10/14 Javascript
基于jQuery和CSS3制作数字时钟附源码下载(jquery篇)
2015/11/24 Javascript
Jquery 1.9.1源码分析系列(十二)之筛选操作
2015/12/02 Javascript
jquery过滤特殊字符',防sql注入的实现方法
2016/08/17 Javascript
jQuery实现页面下拉100像素出现悬浮窗口的方法
2016/09/05 Javascript
浅谈Angular.js中使用$watch监听模型变化
2017/01/10 Javascript
jQuery插件zTree实现更新根节点中第i个节点名称的方法示例
2017/03/08 Javascript
js实现一个猜数字游戏
2017/03/31 Javascript
ES6学习教程之对象字面量详解
2017/10/09 Javascript
使用pkg打包Node.js应用的方法步骤
2018/10/19 Javascript
JavaScript实现星级评价效果
2019/05/17 Javascript
vue keep-alive 动态删除组件缓存的例子
2019/11/04 Javascript
vue项目前端微信JSAPI与外部H5支付相关实现过程及常见问题
2020/04/14 Javascript
解决vue项目中出现Invalid Host header的问题
2020/11/17 Javascript
python实现ftp客户端示例分享
2014/02/17 Python
使用Python脚本来获取Cisco设备信息的示例
2015/05/04 Python
Python Django使用forms来实现评论功能
2016/08/17 Python
分分钟入门python语言
2018/03/20 Python
详解从Django Allauth中进行登录改造小结
2019/12/18 Python
解决tensorflow打印tensor有省略号的问题
2020/02/04 Python
解决virtualenv -p python3 venv报错的问题
2021/02/05 Python
HTML5移动开发图片压缩上传功能
2016/11/09 HTML / CSS
NFL Game Pass欧洲:在线观看NFL比赛直播和点播,以高清质量播放
2018/08/30 全球购物
什么是Remote Module
2016/06/10 面试题
甜点店创业计划书
2014/01/27 职场文书
护理不良事件检讨书
2014/02/06 职场文书
倡议书格式
2014/04/14 职场文书
餐饮投资计划书
2014/04/25 职场文书
春秋淹城导游词
2015/02/11 职场文书
在项目中使用redis做缓存的一些思路
2021/09/14 Redis