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模拟鼠标拖动操作的方法
Mar 11 Python
python使用Image处理图片常用技巧分析
Jun 01 Python
python类装饰器用法实例
Jun 04 Python
从零开始学Python第八周:详解网络编程基础(socket)
Dec 14 Python
Python操作csv文件实例详解
Jul 31 Python
Python3实战之爬虫抓取网易云音乐的热门评论
Oct 09 Python
详解python3中tkinter知识点
Jun 21 Python
Python实现的对一个数进行因式分解操作示例
Jun 27 Python
python基于paramiko将文件上传到服务器代码实现
Jul 08 Python
Python通过类的组合模拟街道红绿灯
Sep 16 Python
Python爬虫过程解析之多线程获取小米应用商店数据
Nov 14 Python
python 爬取吉首大学网站成绩单
Jun 02 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 JSON 数据解析代码
2010/05/26 PHP
基于PHP常用函数的用法详解
2013/05/10 PHP
50个PHP程序性能优化的方法
2014/06/02 PHP
php传值赋值和传地址赋值用法实例分析
2015/06/20 PHP
PHP中OpenSSL加密问题整理
2017/12/14 PHP
php7连接MySQL实现简易查询程序的方法
2020/10/13 PHP
javascript 写的一个简单的timer
2009/07/30 Javascript
得到form下的所有的input的js代码
2013/11/07 Javascript
JS中实现简单Formatter函数示例代码
2014/08/19 Javascript
JS+CSS实现仿msn风格选项卡效果代码
2015/10/22 Javascript
jquery实现移动端点击图片查看大图特效
2020/09/11 Javascript
jQuery插件AjaxFileUpload实现ajax文件上传
2016/05/05 Javascript
使用jQuery实现WordPress中的Ctrl+Enter和@评论回复
2016/05/21 Javascript
jQuery height()、innerHeight()、outerHeight()函数的区别详解
2016/05/23 Javascript
JS正则表达式学习之贪婪和非贪婪模式实例总结
2016/12/26 Javascript
vue组件间通信解析
2017/03/01 Javascript
JS字符串false转boolean的方法(推荐)
2017/03/08 Javascript
vue中的watch监听数据变化及watch中各属性的详解
2018/09/11 Javascript
laypage.js分页插件使用方法详解
2019/07/27 Javascript
jqGrid表格底部汇总、合计行footerrow处理
2019/08/21 Javascript
ES6基础之数组和对象的拓展实例详解
2019/08/22 Javascript
浅析vue中的provide / inject 有什么用处
2019/11/10 Javascript
python中__slots__用法实例
2015/06/04 Python
利用python如何在前程无忧高效投递简历
2019/05/07 Python
python读csv文件时指定行为表头或无表头的方法
2019/06/26 Python
python实现对变位词的判断方法
2020/04/05 Python
使用Numpy对特征中的异常值进行替换及条件替换方式
2020/06/08 Python
python openCV实现摄像头获取人脸图片
2020/08/20 Python
python网络爬虫实现发送短信验证码的方法
2021/02/25 Python
Fairyseason:为个人和批发商提供女装和配件
2017/03/01 全球购物
Viking Direct爱尔兰:办公用品和家具
2019/11/21 全球购物
一套C#面试题
2013/10/09 面试题
入学申请自荐信范文
2014/02/26 职场文书
自考毕业自我鉴定
2014/03/18 职场文书
2016入党培训心得体会范文
2016/01/08 职场文书
三十年再续同学情倡议书
2019/11/27 职场文书