当前位置: 首页 > article >正文

【Python】解析 XML

1、Python 对 XML 的解析

1.1 SAX (simple API for XML )

SAX 解析器使用事件驱动模型,通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。

xml.sax 模块牺牲了便捷性来换取速度和内存占用。

事件驱动指一种基于回调(callback)机制的程序运行方法。

利用SAX解析XML文档牵涉到两个部分:

  • 解析器:负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件。
  • 事件处理器:负责对事件作出响应,对传递的XML数据进行处理。

SAX适用场景:

  • 对大型文件进行处理;
  • 只需要文件的部分内容,或者只需从文件中得到特定信息。
  • 想建立自己的对象模型的时候。

1.2 DOM(Document Object Model)

DOM 解析器在任何处理开始之前,必须把基于XML文件生成的树状数据放在内存,所以DOM解析器的内存使用量完全根据输入资料的大小。

  • xml.dom.minidom
    minidom 是DOM API的极简化实现,比完整版的DOM要简单的多,而且这个包也小的多。
  • xml.dom.pulldom
    pulldom模块提供的是一个“pull解析器”,其背后的基本概念指的是从XML流中pull事件,然后进行处理。虽然与SAX一样采用事件驱动模型(event-driven processing model),但是不同的是,使用pull解析器时,使用者需要明确地从XML流中pull事件,并对这些事件遍历处理,直到处理完成或者出现错误。

1.3 ElementTree(元素树)

xml.etree.ElementTree 模块提供了一个轻量级、Pythonic的API,同时还有一个高效的C语言实现,即 xml.etree.cElementTree

与 DOM 相比,ET的速度更快,API使用更直接、方便。
与 SAX 相比,ET.iterparse 函数同样提供了按需解析的功能,不会一次性在内存中读入整个文档。ET的性能与SAX模块大致相仿,但是它的API更加高层次,用户使用起来更加便捷。

1.4 xml.parser.expat

xml.parser.expat 提供了对C语言编写的expat解析器的一个直接的、底层API接口。expat接口与SAX类似,也是基于事件回调机制,但是这个接口并不是标准化的,只适用于expat库。

expat是一个面向流的解析器。您注册的解析器回调(或handler)功能,然后开始搜索它的文档。当解析器识别该文件的指定的位置,它会调用该部分相应的处理程序(如果您已经注册的一个)。该文件被输送到解析器,会被分割成多个片断,并分段装到内存中。因此expat可以解析那些巨大的文件。

1.5 lxml

lxml 是一个第三方库,它提供了更强大的XML处理功能,包括XPath支持、XML Schema验证、HTML支持等。

1.6 xmltodict

xmltodict是一个第三方库,它提供了一个功能,将Python的字典对象转换为XML,反之亦然。

2、示例

XML 实例文件 movies.xml 内容如下:

<collection shelf="New Arrivals">
<movie title="Enemy Behind">
   <type>War, Thriller</type>
   <format>DVD</format>
   <year>2003</year>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Talk about a US-Japan war</description>
</movie>
<movie title="Transformers">
   <type>Anime, Science Fiction</type>
   <format>DVD</format>
   <year>1989</year>
   <rating>R</rating>
   <stars>8</stars>
   <description>A schientific fiction</description>
</movie>
   <movie title="Trigun">
   <type>Anime, Action</type>
   <format>DVD</format>
   <episodes>4</episodes>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Vash the Stampede!</description>
</movie>
<movie title="Ishtar">
   <type>Comedy</type>
   <format>VHS</format>
   <rating>PG</rating>
   <stars>2</stars>
   <description>Viewable boredom</description>
</movie>
</collection>

2.1 xml.sax

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
import xml.sax
 
class MovieHandler( xml.sax.ContentHandler ):
   def __init__(self):
      self.CurrentData = ""
      self.type = ""
      self.format = ""
      self.year = ""
      self.rating = ""
      self.stars = ""
      self.description = ""
 
   # 元素开始事件处理
   def startElement(self, tag, attributes):
      self.CurrentData = tag
      if tag == "movie":
         print "*****Movie*****"
         title = attributes["title"]
         print "Title:", title
 
   # 元素结束事件处理
   def endElement(self, tag):
      if self.CurrentData == "type":
         print "Type:", self.type
      elif self.CurrentData == "format":
         print "Format:", self.format
      elif self.CurrentData == "year":
         print "Year:", self.year
      elif self.CurrentData == "rating":
         print "Rating:", self.rating
      elif self.CurrentData == "stars":
         print "Stars:", self.stars
      elif self.CurrentData == "description":
         print "Description:", self.description
      self.CurrentData = ""
 
   # 内容事件处理
   def characters(self, content):
      if self.CurrentData == "type":
         self.type = content
      elif self.CurrentData == "format":
         self.format = content
      elif self.CurrentData == "year":
         self.year = content
      elif self.CurrentData == "rating":
         self.rating = content
      elif self.CurrentData == "stars":
         self.stars = content
      elif self.CurrentData == "description":
         self.description = content
  
if ( __name__ == "__main__"):
   
   # 创建一个 XMLReader
   parser = xml.sax.make_parser()
   # turn off namepsaces
   parser.setFeature(xml.sax.handler.feature_namespaces, 0)
 
   # 重写 ContextHandler
   Handler = MovieHandler()
   parser.setContentHandler( Handler )
   
   parser.parse("movies.xml")

运行结果:

*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Year: 2003
Rating: PG
Stars: 10
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Year: 1989
Rating: R
Stars: 8
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Stars: 10
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Stars: 2
Description: Viewable boredom

2.2 xml.dom

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
from xml.dom.minidom import parse
import xml.dom.minidom
 
# 使用minidom解析器打开 XML 文档
DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
   print "Root element : %s" % collection.getAttribute("shelf")
 
# 在集合中获取所有电影
movies = collection.getElementsByTagName("movie")
 
# 打印每部电影的详细信息
for movie in movies:
   print "*****Movie*****"
   if movie.hasAttribute("title"):
      print "Title: %s" % movie.getAttribute("title")
 
   type = movie.getElementsByTagName('type')[0]
   print "Type: %s" % type.childNodes[0].data
   format = movie.getElementsByTagName('format')[0]
   print "Format: %s" % format.childNodes[0].data
   rating = movie.getElementsByTagName('rating')[0]
   print "Rating: %s" % rating.childNodes[0].data
   description = movie.getElementsByTagName('description')[0]
   print "Description: %s" % description.childNodes[0].data

运行结果:

Root element : New Arrivals
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Rating: PG
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Rating: R
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Description: Viewable boredom

2.3 xml.etree.ElementTree

import xml.etree.ElementTree as ET

xml_string = '''
        <book id="10086">
            <title lang="en">Good Omens</title>
            <authors>
                <name>Neil Gaiman</name>
                <name>Terry Pratchett</name>
            </authors>
            <year>1990</year>
        </book>
    '''

root = ET.fromstring(xml_string)

# 获取根元素的标签
print(root.tag)

# 获取根元素的文本内容
print(root.text)

# 获取根元素的属性
print(root.attrib)

# 查找第一个title元素
print(root.find("title").text)

# 查找所有author元素
names = root.find("authors").findall("name")
for name in names:
    print(name.text)

# 修改title元素的文本内容
root.find("title").text = "The Nice and Accurate Prophecies of Agnes Nutter, Witch"

# 添加一个新的元素
new_year = ET.SubElement(root, "year")
new_year.text = "2024"

# 将修改后的元素转换为字符串
new_xml_string = ET.tostring(root, encoding="unicode")
print(new_xml_string)

运行结果:

book

            
{'id': '10086'}
Good Omens
Neil Gaiman
Terry Pratchett
<book id="10086">
            <title lang="en">The Nice and Accurate Prophecies of Agnes Nutter, Witch</title>
            <authors>
                <name>Neil Gaiman</name>
                <name>Terry Pratchett</name>
            </authors>
            <year>1990</year>
        <year>2024</year></book>     

10、资料

  • Python xml
  • Python 解析 XML 数据
  • Python xml 解析
  • Python SAX

http://www.kler.cn/a/389479.html

相关文章:

  • HelloMeme 上手即用教程
  • DeBiFormer实战:使用DeBiFormer实现图像分类任务(二)
  • 【学习笔记】数据结构(七)
  • 如何提高自动驾驶中惯性和卫星组合导航pbox的精度?
  • SQL练习(2)
  • 将大型语言模型(如GPT-4)微调用于文本续写任务
  • Linux学习笔记之定时任务调度
  • Spring学习笔记(三)
  • [Linux] 进程间通信
  • 【C】一文速学----线程池原理与实战
  • 18. 友元
  • 分享三个python爬虫案例
  • ServletContext介绍
  • 别再为视频转文字烦恼啦!这10个转换工具帮你一键搞定。
  • UE5 随机生成地牢关卡
  • Python酷库之旅-第三方库Pandas(206)
  • 信息安全数学基础(47)域的结构
  • 浔川 AI 翻译 v5.0 上线时间相关公告
  • canal配置之一:admin配置
  • 手边酒店多商户版V2源码独立部署_博纳软云
  • 多智能体系统的构建
  • C++线程
  • 【大数据学习 | kafka高级部分】kafka的快速读写
  • 道品科技水肥一体化在农业生产中的必要性与应用领域探讨
  • 微服务架构面试内容整理-消息驱动-RocketMQ
  • redis RDB持久化技术