Python XML解析
参考:https://www.runoob.com/python/python-xml.html
什么是XML
XML 指可扩展标记语言(eXtensible Markup Language)。
XML被设计用来传输和存储数据。
XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识。
它也是元标记语言,即定义了用于定义其他于特定领域有关的,语义的,结构化的标记语言的句法语言。
Python对XML的解析
常见的 XML 编程接口有 DOM 和 SAX,这两种接口处理 XML 文件的方式不同,当然使用场合也不同。
Python 有三种方法解析 XML,SAX,DOM,以及 ElementTree:
1,SAX(simple API for XML )
Python 标准库包含 SAX 解析器,SAX 用事件驱动模型,通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。
2,DOM(Document Object Model)
将 XML 数据在内存中解析成一个树,通过对树的操作来操作XML。
3,ELementTree(元素数)
ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。
注:因DOM需要将XML数据映射到内存中的树,一是比较慢,二是比较耗内存,而SAX流式读取XML文件,比较快,占用内存少,但需要用户实现回调函数(handler)。
本章节使用到的 XML 实例文件 movies.xml 内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <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> |
本文介绍SAX和DOM两种方式
python使用SAX解析xml
SAX是一种基于实践取得的API
利用SAX解析文档涉及到两个部分:解析器和事件处理器。
解析器赋值读取XML文档,并像事件处理器发送事件,如元素开始跟元素结束事件。
而事件处理器则负责对事件作出相应,对传递的XML数据进处理。
1,对大型文件进行处理
2,只需要文件的部分内容,或者值需从文件中得到特定的信息。
3,想建立自己的对象模型时。
在python中使用sax方式处理xml要先引入xml.sax中的parse函数,还有xml.sax.handler中的ContentHandler类。
ContentHandler类方法介绍
characters(content)方法
调用事件:
从行开始,遇到标签之前,存在字符,content的值为这些字符串。
从一个标签,遇到下一个标签之前, 存在字符,content 的值为这些字符串。
从一个标签,遇到行结束符之前,存在字符,content 的值为这些字符串。
标签可以是开始标签,也可以是结束标签。
startDocument() 方法
文档启动的时候调用。
endDocument() 方法
解析器到达文档结尾时调用。
startElement(name, attrs)方法
遇到XML开始标签时调用,name是标签的名字,attrs是标签的属性值字典。
endElement(name) 方法
遇到XML结束标签时调用。
注意:一般使用startElement(name, attrs),characters(content),endElement(name) 这3个方法
startDoeument() 和endDocument()方法使用较少
make_parser方法
以下方法创建一个新的解析器对象并返回
1 | xml.sax.make_parser( [parser_list] ) |
参数说明:
1 | parser_list - 可选参数,解析器列表 |
parse方法
以下方法创建一个 SAX 解析器并解析xml文档:
1 | xml.sax.parse( xmlfile, contenthandler[, errorhandler]) |
参数说明
1 2 3 | xmlfile - xml文件名 contenthandler - 必须是一个ContentHandler的对象 errorhandler - 如果指定该参数,errorhandler必须是一个SAX ErrorHandler对象 |
parseString方法
parseString方法创建一个XML解析器并解析xml字符串:
1 | xml.sax.parseString(xmlstring, contenthandler[, errorhandler]) |
参数说明
1 2 3 | xmlstring - xml字符串 contenthandler - 必须是一个ContentHandler的对象 errorhandler - 如果指定该参数,errorhandler必须是一个SAX ErrorHandler对象 |
下面举例说明
创建一个ContentHandler类并使用该类处理XML文本
以下代码只在类里面使用一个print打印
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # 只演示执行过程不实际处理数据start # 导入模块 import xml.sax # 创建一个Handler类继承xml.sax.ContentHandler类 class Handler(xml.sax.ContentHandler): def startDocument( self ): print ( 'startDocument...' ) def startElement( self ,name,attr): print ( 'startElement...' ) def characters( self ,text): print ( 'characters...' ) def endElement( self ,name): print ( 'endElement...' ) def endDocument( self ): print ( 'endDocument...' ) H = Handler() test_xml = '<a href="/">python</a>' xml_str = xml.sax.parseString(test_xml,H) # 输出如下 # startDocument... # startElement... # characters... # endElement... # endDocument... # 只演示执行过程不实际处理数据end |
从输出可以明显看出执行的顺序为
1 2 3 4 5 | # startDocument # startElement # characters # endElement # endDocument |
以下代码演示各个方法参数对应的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # 演示参数start # 导入模块 import xml.sax # 创建一个Handler类继承xml.sax.ContentHandler类 class Handler(xml.sax.ContentHandler): def startElement( self ,name,attr): print ( 'startElement...' ) print ( '标签名字为 %s' % (name)) print ( '标签属性字典%s' % (attr.items())) def characters( self ,text): print ( 'characters...' ) print ( '标签内部内容为%s' % (text)) def endElement( self ,name): print ( 'endElement...' ) print ( '标签名字为 %s' % (name)) H = Handler() test_xml = '<a href="/">python</a>' xml_str = xml.sax.parseString(test_xml,H) # 输出如下 # startElement... # 标签名字为 a # 标签属性字典[('href', '/')] # characters... # 标签内部内容为python # endElement... # 标签名字为 a # 演示参数end |
解析
1 2 3 4 | 本次分析的XML为 '<a href="/">python</a>' 标签名字为a 标签的写法为< str >< / str >名字即 str 标签是属性为标签内定义的属性(可为空)即不定义属性,本次定了为href = "/" attr为标签是属性字典,使用items即可显示内容 标签的内容及<a>< / a>之间的文本 本次为 'python' |
本次打开的是字符串,如果需要解析xml文档则把xml文档内容保存成文档然后使用以下方法调用
1 | xml.sax.parse( 'test.xml' ,H) |
Python解析实例
为了便于分析,本次把示例只保留一部电影
movies.xml
1 2 3 4 5 6 7 8 9 10 | <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> < / collection> |
解析代码如下
use_sax_xml.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | # 使用sax解析movies start import xml.sax class MoviesHandler(xml.sax.ContentHandler): def __init__( self ): self .currentdata = '' self . type = '' self . format = '' self .year = '' self .rating = '' self .stars = '' self .description = '' def startElement( self ,name,attr): self .currentdata = name if self .currentdata = = 'movie' : print ( '***movies***' ) title = attr[ 'title' ] print ( 'Tiele:%s' % (title)) def characters( self ,text): if self .currentdata = = "type" : self . type = text elif self .currentdata = = "format" : self . format = text elif self .currentdata = = "year" : self .year = text elif self .currentdata = = "rating" : self .rating = text elif self .currentdata = = "stars" : self .stars = text elif self .currentdata = = "description" : self .description = text def endElement( self ,name): 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 = "" H = MoviesHandler() xml.sax.parse( 'movies.xml' ,H) # 使用sax解析movies end |
运行输出如下
1 2 3 4 5 6 7 8 | * * * movies * * * Tiele:Enemy Behind Type : War, Thriller Format : DVD Year: 2003 Rating: PG Stars: 10 Description: Talk about a US - Japan war |
使用调试模式查看执行过程
省略几步 依次处理了以下标签
1 2 3 4 5 | < format >DVD< / format > <year> 2003 < / year> <rating>PG< / rating> <stars> 10 < / stars> <description>Talk about a US - Japan war< / description> |
处理完以上标签输出如下
由此可以知道使用SAX执行是逐条语句执行,不需要一次性读取文件至内存
优点是节约内存,缺点是需要执行写方法,效率低。
使用xml.dom解析xml
文件对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口。
一个 DOM 的解析器在解析一个 XML 文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后你可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件。
python中用xml.dom.minidom来解析xml文件,示例如下:
使用DOM解析是一次性读取整个文档在内存中生成一个树结构,相比SAX使用更加简单,缺点是占用内存,但是目前服务器内存相对较大,从程序员节约写代码时间来看,可以优先选用DOM。
DOM解析方法参考:https://www.cnblogs.com/minseo/p/15187837.html
代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # 使用dom解析movies start # 导入模块 import xml.dom.minidom # 打开xml文档 dom = xml.dom.minidom.parse( 'movies.xml' ) # dom.documentElement的到元素对象 movies = dom.documentElement.getElementsByTagName( 'movie' ) # getElementsByTagName('movie')从元素对象总查找标签名为movie的对象 # 得到的对象会组成一个对象列表,本次的对象只有一个 for movie in movies: print ( "*****Movie*****" ) # 如果对象有属性值title即电影名则打印 if movie.hasAttribute( "title" ): print ( "Title: %s" % movie.getAttribute( "title" )) # 在从得到的对象中间在搜索对应的标签名对象,本次找的的对象也是一个 # 使用[0]下标取得取得 # 使用firstChild.data获取对象的值打印 type = movie.getElementsByTagName( 'type' )[ 0 ] print ( "Type: %s" % type .firstChild.data) format = movie.getElementsByTagName( 'format' )[ 0 ] print ( "Format: %s" % format .firstChild.data) rating = movie.getElementsByTagName( 'rating' )[ 0 ] print ( "Rating: %s" % rating.firstChild.data) description = movie.getElementsByTagName( 'description' )[ 0 ] print ( "Description: %s" % description.firstChild.data) # 使用dom解析movies end |
输出结果和使用SAX输出是一样的,只不过使用DOM方法代码更加简洁清晰
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!