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

问题

你想解析某个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文档的资料请关注我们其它相关文章!

(0)

相关推荐

  • Python lxml解析HTML并用xpath获取元素的方法

    代码 使用方法见注释 #-*- coding: UTF-8 -*- from lxml import etree source = u''' <div><p class="p1" data-a="1">测试数据1</p> <p class="p1" data-a="2">测试数据2</p> <p class="p1" data-a="

  • Python minidom模块用法示例【DOM写入和解析XML】

    本文实例讲述了Python minidom模块用法.分享给大家供大家参考,具体如下: 一.DOM写XML文件 # -*- coding:utf-8 -*- #!python3 #导入minidom from xml.dom import minidom # 1.创建DOM树对象 dom=minidom.Document() # 2.创建根节点.每次都要用DOM对象来创建任何节点. root_node=dom.createElement('root') # 3.用DOM对象添加根节点 dom.ap

  • python读取xml文件方法解析

    关于python读取xml文章很多,但大多文章都是贴一个xml文件,然后再贴个处理文件的代码.这样并不利于初学者的学习,希望这篇文章可以更通俗易懂的教如何使用python来读取xml文件. 什么是xml? xml即可扩展标记语言,它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言. abc.xml <?xml version="1.0" encoding="utf-8"?> <catalog> <maxid

  • Python命名空间的本质和加载顺序

    Python的命名空间是Python程序猿必须了解的内容,对Python命名空间的学习,将使我们在本质上掌握一些Python中的琐碎的规则. 接下来我将分四部分揭示Python命名空间的本质:一.命名空间的定义:二.命名空间的查找顺序:三.命名空间的生命周期:四.通过locals()和globals() BIF访问命名空间 重点是第四部分,我们将在此部分观察命名空间的内容. 一.命名空间 Python使用叫做命名空间的东西来记录变量的轨迹.命名空间是一个 字典(dictionary) ,它的键就

  • Python进阶_关于命名空间与作用域(详解)

    写在前面 如非特别说明,下文均基于Python3 命名空间与作用于跟名字的绑定相关性很大,可以结合另一篇介绍Python名字.对象及其绑定的文章. 1. 命名空间 1.1 什么是命名空间 Namespace命名空间,也称名字空间,是从名字到对象的映射.Python中,大部分的命名空间都是由字典来实现的,但是本文的不会涉及命名空间的实现.命名空间的一大作用是避免名字冲突: def fun1(): i = 1 def fun2(): i = 2 同一个模块中的两个函数中,两个同名名字i之间绝没有任何

  • python解析xml文件方式(解析、更新、写入)

    Overview 这篇博客内容将包括对XML文件的解析.追加新元素后写入到XML,以及更新原XML文件中某结点的值.使用的是python的xml.dom.minidom包,详情可见其官方文档:xml.dom.minidom官方文档.全文都将围绕以下的customer.xml进行操作: <?xml version="1.0" encoding="utf-8" ?> <!-- This is list of customers --> <c

  • Python3使用xml.dom.minidom和xml.etree模块儿解析xml文件封装函数的方法

    总结了一下使用Python对xml文件的解析,用到的模块儿如下: 分别从xml字符串和xml文件转换为xml对象,然后解析xml内容,查询指定信息字段. from xml.dom.minidom import parse, parseString from xml.etree import ElementTree import xml.dom.minidom """ Get XML String info 查询属性值 response:xml string tag:xml t

  • Python3基于sax解析xml操作示例

    本文实例讲述了Python3基于sax解析xml操作.分享给大家供大家参考,具体如下: python使用SAX解析xml SAX是一种基于事件驱动的API. 利用SAX解析XML文档牵涉到两个部分:解析器和事件处理器. 解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件; 而事件处理器则负责对事件作出相应,对传递的XML数据进行处理. 1.对大型文件进行处理: 2.只需要文件的部分内容,或者只需从文件中得到特定信息. 3.想建立自己的对象模型的时候. 在python中使用

  • Python基于lxml模块解析html获取页面内所有叶子节点xpath路径功能示例

    本文实例讲述了Python基于lxml模块解析html获取页面内所有叶子节点xpath路径功能.分享给大家供大家参考,具体如下: 因为需要使用叶子节点的路径来作为特征,但是原始的lxml模块解析之后得到的却是整个页面中所有节点的xpath路径,不是我们真正想要的形式,所以就要进行相关的处理才行了,差了很多网上的博客和文档也没有找到一个是关于输出html中全部叶子节点的API接口或者函数,也可能是自己没有那份耐心,没有找到合适的资源,只好放弃了寻找,但是这并不说明没有其他的方法了,在对页面全部节点

  • python实现XML解析的方法解析

    这篇文章主要介绍了python实现XML解析的方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 三种方法:一是xml.dom.*模块,它是W3C DOM API的实现,若需要处理DOM API则该模块很适合:二是xml.sax.*模块,它是SAX API的实现,这个模块牺牲了便捷性来换取速度和内存占用,SAX是一个基于事件的API,这就意味着它可以"在空中"处理庞大数量的的文档,不用完全加载进内存:三是xml.etree.Ele

  • 解读Python编程中的命名空间与作用域

    变量是拥有匹配对象的名字(标识符).命名空间是一个包含了变量名称们(键)和它们各自相应的对象们(值)的字典. 一个Python表达式可以访问局部命名空间和全局命名空间里的变量.如果一个局部变量和一个全局变量重名,则局部变量会覆盖全局变量. 每个函数都有自己的命名空间.类的方法的作用域规则和通常函数的一样. Python会智能地猜测一个变量是局部的还是全局的,它假设任何在函数内赋值的变量都是局部的. 因此,如果要给全局变量在一个函数里赋值,必须使用global语句. global VarName的

  • Python中将字典转换为XML以及相关的命名空间解析

    尽管 xml.etree.ElementTree 库通常用来做解析工作,其实它也可以创建XML文档. 例如,考虑如下这个函数: from xml.etree.ElementTree import Element def dict_to_xml(tag, d): ''' Turn a simple dict of key/value pairs into XML ''' elem = Element(tag) for key, val in d.items(): child = Element(k

  • Python Django 命名空间模式的实现

    新建一个项目 app02 在 app02/ 下创建 urls.py: from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^blog/', views.test, name="blog"), ] app01/urls.py: from django.conf.urls import url from app01 import views urlpatterns = [ url(r'

  • python3解析库lxml的安装与基本使用

    前言 在爬虫的学习中,我们爬取网页信息之后就是对信息项匹配,这个时候一般是使用正则.但是在使用中发现正则写的不好的时候不能精确匹配(这其实是自己的问题!)所以就找啊找.想到了可以通过标签来进行精确匹配岂不是比正则要快.所以找到了lxml. lxml是python的一个解析库,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高 XPath,全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜寻XML文档的,但是它同样适用

  • python解析xml简单示例

    本文实例讲述了python解析xml的方法.分享给大家供大家参考,具体如下: xml是除了json之外另外一个比较常用的用来做为数据交换的载体格式.对于一些比较固定的数据,直接保存在xml中,还可以免去去数据库中查询的麻烦.而且直接读小文件,性能比查询数据库应该更好,下面一个例子,如何用python解析xml数据,xml数据是省份,城市 数据,内容如下: <?xml version="1.0" encoding="utf-8" ?> <countr

随机推荐