专业编程基础技术教程

网站首页 > 基础教程 正文

Python解析XML的三种常用方式

ccvgpt 2024-08-05 12:18:18 基础教程 13 ℃

一、什么是 XML?

XML 被设计用来传输和存储数据。它也是元标记语言,即定义了用于定义其他与特定领域有关的、语义的、结构化的标记语言的句法语言。

Python解析XML的三种常用方式

准备一个解析用的xml,保存为"测试.xml",内容如下:

 <?xml version = "1.0" encoding = "utf-8"?>
 <data>
 <account name="laoz">
 <id>1</id>
 <username>laoz</username>
 <realname>老曾</realname>
 <age>30</age>
 <sex>男</sex>
 <url>http://hi-laoz.com</url>
 <description>我是老曾</description>
 </account>
 <account name="强子">
 <id>2</id>
 <username>qz</username>
 <realname>强子</realname>
 <age>30</age>
 <sex>男</sex>
 <url>http://1668s.com</url>
 <description>我是强子</description>
 </account>
 </data>

1、第一行是 XML 声明

它定义 XML 的版本(1.0)和所使用的编码(utf-8 : 万国码, 可显示各种语言)

2、必须包含根元素(有且只有一个)

该元素是所有其他元素的父元素,这里的根元素是Data

<Data>
..
</Data>

所有的<account>都被包含在<Data>里面

3、元素开始标签必须要有结束标签

< account > 元素有 6个子元素:<id>、<username>、<realname>

、<age>、<sex>、<url>、< description >

每个元素都有对应的关闭标签(跟HTML不一样,有一些是不需要关闭的,比如<p>,<br>)

4、XML 标签对大小写敏感

比如<Data>和<DATA>是不一样的

5、XML 属性值必须加引号

< account name=laoz>这样会报错的,必须"laoz"才行

二、Python 对 XML 的解析

Python 有三种方法解析 XML,SAX,DOM,以及 ElementTree。

DOM会把整个XML读入内存,解析为树,因此占用内存大,解析慢,优点是可以任意遍历树的节点。SAX是流模式,边读边解析,占用内存小,解析快,缺点是我们需要自己处理事件。

1、利用DOM解析XML

一个 DOM 的解析器在解析一个 XML 文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后你可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件。

 
 from xml.dom.minidom import parse
 import xml.dom.minidom
 
 # 使用minidom解析器打开 XML 文档
 DOMTree = xml.dom.minidom.parse("测试.xml")
 collection = DOMTree.documentElement
 if collection.hasAttribute("shelf"):
 print ("Root element : %s" % collection.getAttribute("shelf"))
 
 # 在集合中获取所有account
 accounts = collection.getElementsByTagName("account")
 
 # 打印每个账号的详细信息
 for account in accounts:
 print ("*****账号*****")
 if account.hasAttribute("name"):
 print ("标签: %s" % account.getAttribute("name"))
 realname = account.getElementsByTagName('realname')[0] # [0]:若存在同名的,用以区分
 print ("姓名: %s" % realname.childNodes[0].data) # type.childNodes[0]表示type标签下的第一个内容或者子标签
 username = account.getElementsByTagName('username')[0]
 print ("用户名: %s" % username.childNodes[0].data)
 sex = account.getElementsByTagName('sex')[0]
 print ("性别: %s" % sex.childNodes[0].data)
 age = account.getElementsByTagName('age')[0]
 print("年龄: %s" % age.childNodes[0].data)
 url = account.getElementsByTagName('url')[0]
 print("主页: %s" % url.childNodes[0].data)
 description = account.getElementsByTagName('description')[0]
 print ("内容: %s" % description.childNodes[0].data)

2、利用SAX解析XML

SAX是一种基于事件驱动的API。利用SAX解析XML文档牵涉到两个部分:解析器和事件处理器。解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件;而事件处理器则负责对事件作出相应,对传递的XML数据进行处理。

 import xml.sax
 
 class accountHandler(xml.sax.ContentHandler):
 def __init__(self):
 self.CurrentData = ""
 self.id=""
 self.username = ""
 self.realname = ""
 self.age = ""
 self.sex = ""
 self.url = ""
 self.description = ""
 
 # 元素开始调用
 def startElement(self, tag, attributes):
 self.CurrentData = tag
 if tag == "account":
 print("*****account*****")
 name = attributes["name"]
 print("name:", name)
 
 # 元素结束调用
 def endElement(self, tag):
 if self.CurrentData == "id":
 print("id:", self.id)
 elif self.CurrentData == "username":
 print("账号:", self.username)
 elif self.CurrentData == "realname":
 print("姓名:", self.realname)
 elif self.CurrentData == "age":
 print("年龄:", self.age)
 elif self.CurrentData == "sex":
 print("性别:", self.sex)
 elif self.CurrentData == "url":
 print("主页:", self.url)
 elif self.CurrentData == "description":
 print("简介:", self.description)
 self.CurrentData = ""
 
 # 读取字符时调用
 def characters(self, content):
 if self.CurrentData == "id":
 self.id = content
 elif self.CurrentData == "username":
 self.username = content
 elif self.CurrentData == "realname":
 self.realname = content
 elif self.CurrentData == "age":
 self.age = content
 elif self.CurrentData == "sex":
 self.sex = content
 elif self.CurrentData == "url":
 self.url = 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 = accountHandler()
 parser.setContentHandler(Handler)
 
 parser.parse("测试.xml")

3、利用ElementTree解析XML

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

Python标准库中,提供了ElementTree的两种实现。一个是纯Python实现的xml.etree.ElementTree,另一个是速度更快的C语言实现xml.etree.cElementTree。使用C语言实现的速度要快很多,而且内存消耗也要少很多。Python 3.3之后, ElemenTree模块会自动优先使用C加速器,如果不存在C实现,则会使用Python实现。因此,使用Python 3.3+的朋友,只需要import xml.etree.ElementTree即可。

 # 两种方式,尽量使用cElementTree,他的速度要快
 import xml.etree.cElementTree as ET
 # import xml.etree.ElementTree as ET
 tree = ET.parse("测试.xml")
 #root = ET.fromstring(country_data_as_string) #导入字符串
 root = tree.getroot() #前三句导入数据并获取根元素
 print (root.tag) #取标签名
 print (root.attrib) #取属性(字典形式)
 for account in root:
 print ('*'*30)
 print ("name:", account.attrib['name']) #取属性值
 print ("id:", account[0].text) #取子节点的内容(元素值)
 print("账号:", account[1].text) # 取子节点的内容(元素值)
 print("姓名:", account[2].text) # 取子节点的内容(元素值)
 print("年龄:", account[3].text) # 取子节点的内容(元素值)
 print("性别:", account[4].text) # 取子节点的内容(元素值)
 print("主页:", account[5].text) # 取子节点的内容(元素值)
 print("简介:", account[6].text) # 取子节点的内容(元素值)

Tags:

最近发表
标签列表