首页 > 编程语言 >python解析XML

python解析XML

时间:2023-05-21 21:07:56浏览次数:47  
标签:XML xml name python gender self stu 解析 id

  1. xml简介
    XML 全称 Extensible Markup Language,中文译为可扩展标记语言。XML 之前有两个先行者:SGML 和 HTML,率先登场的是 SGML, 尽管它功能强大,但文档结构复杂,既不容易学也不易于使用,因此几个主要的浏览器厂商均拒绝支持 SGML,这些因素限制了 SGML 在网上的传播性;1989 年 HTML 登场,它继承了 SGML 诸多优点,去除了 SGML 复杂庞大的缺点,HTML 在数据显示上表现十分出色,但它的语法是不可扩展的,因此其无法描述数据、可读性差,没办法人们再次将目光转向 SGML,经过对 SGML 一系列改造,终于在 1998 年,XML 第一个版本问世。
    上面说了那么多,简单来说就是:XML 和 HTML 均由 SGML 改造而来,HTML 是一种页面技术,聚焦的是数据的显示,而 XML 易于扩展,主要用来传送和存储数据,聚焦的是数据的内容。
  2. 解析方式
    Python 有三种 XML 解析方式:SAX(simple API for XML)、DOM(Document Object Model)、ElementTree。
  • DOM 方式:DOM 中文译为文档对象模型,是 W3C 组织推荐的标准编程接口,它将 XML 数据在内存中解析成一个树,通过对树的操作来操作 XML。
  • SAX 方式:SAX 是一个用于处理 XML 事件驱动的模型,它逐行扫描文档,一边扫描一边解析,对于大型文档的解析拥有巨大优势,尽管不是 W3C 标准,但它却得到了广泛认可。
  • ElementTree 方式:ElementTree 相对于 DOM 来说拥有更好的性能,与 SAX 性能差不多,API 使用也很方便。
  1. 具体实现
    test.xml
<?xml version="1.0" encoding="utf-8"?>
<list>
<student id="stu1" name="stu">
   <id>1001</id>
   <name>张三</name>
   <age>22</age>
   <gender>男</gender>
</student>
<student id="stu2" name="stu">
   <id>1002</id>
   <name>李四</name>
   <age>21</age>
   <gender>女</gender>
</student>
</list>

DOM 方式解析
使用 DOM 方式,首先要对其 API 有一定了解,如果不了解,网上的教程也比较多,比如:DOM 教程,下面看一下使用示例。

from xml.dom.minidom import parse

# 读取文件
dom = parse('test.xml')
# 获取文档元素对象
data = dom.documentElement
# 获取 student
stus = data.getElementsByTagName('student')
for stu in stus:
	# 获取标签属性值
    st_id = stu.getAttribute('id')
    st_name = stu.getAttribute('name')
	# 获取标签中内容
    id = stu.getElementsByTagName('id')[0].childNodes[0].nodeValue
    name = stu.getElementsByTagName('name')[0].childNodes[0].nodeValue
    age = stu.getElementsByTagName('age')[0].childNodes[0].nodeValue
    gender = stu.getElementsByTagName('gender')[0].childNodes[0].nodeValue
    print('st_id:', st_id,  ', st_name:',st_name)
    print('id:', id, ', name:', name, ', age:', age, ', gender:',gender)

 结果:

st_id: stu1 , st_name: stu
id: 1001 , name: 张三 , age: 22 , gender: 男
st_id: stu2 , st_name: stu
id: 1002 , name: 李四 , age: 21 , gender: 女

 通过输出结果,我们可以发现已经获取了标签属性值和标签内容了。

SAX 方式解析

使用 SAX 解析 XML 文档主要涉及到解析器和事件处理器,解析器负责读取 XML 文档,并向事件处理器发送事件,事件处理器负责对事件作出响应,对传递的 XML 数据进行处理。

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 结束标签时调用。

下面通过示例看一下如何通过 SAX 方式解析 XML。

import xml.sax

class StudentHandler(xml.sax.ContentHandler):
    def __init__(self):
        self.id = ""
        self.name = ""
        self.age = ""
        self.gender = ""

    # 元素开始调用
    def startElement(self, tag, attributes):
        self.CurrentData = tag
        if tag == "student":
            stu_name = attributes["name"]
            print("stu_name:", stu_name)

    # 元素结束调用
    def endElement(self, tag):
        if self.CurrentData == "id":
            print("id:", self.id)
        elif self.CurrentData == "name":
            print("name:", self.name)
        elif self.CurrentData == "age":
            print("age:", self.age)
        elif self.CurrentData == "gender":
            print("gender:", self.gender)
        self.CurrentData = ""

    # 读取字符时调用
    def characters(self, content):
        if self.CurrentData == "id":
            self.id = content
        elif self.CurrentData == "name":
            self.name = content
        elif self.CurrentData == "age":
            self.age = content
        elif self.CurrentData == "gender":
            self.gender = content

if (__name__ == "__main__"):
    # 创建 XMLReader
    parser = xml.sax.make_parser()
    # 关闭命名空间
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)
    # 重写 ContextHandler
    Handler = StudentHandler()
    parser.setContentHandler(Handler)
    parser.parse("test.xml")

 输出结果:

stu_name: stu
id: 1001
name: 张三
age: 22
gender: 男
stu_name: stu
id: 1002
name: 李四
age: 21
gender: 女

 ElementTree 方式解析
Python 提供了两种 ElementTree 的实现方式。一个是纯 Python 实现的 xml.etree.ElementTree,另一个是 C 语言实现 xml.etree.cElementTree,使用 C 语言实现的方式速度更快且内存消耗更少。Python3.3 之后,ElemenTree 模块会自动优先使用 C 加速器,如果不存在 C 实现,则会使用 Python 实现。因此,使用 Python3.3+ 时,只需要 import xml.etree.ElementTree 即可。
下面看一下示例

import xml.etree.ElementTree as ET

tree = ET.parse("test.xml")
# 根节点
root = tree.getroot()
# 标签名
print('root_tag:',root.tag)
for stu in root:
    # 属性值
    print ("stu_name:", stu.attrib["name"])
    # 标签中内容
    print ("id:", stu[0].text)
    print ("name:", stu[1].text)
    print("age:", stu[2].text)
    print("gender:", stu[3].text)

 输出结果:

root_tag: list
stu_name: stu
id: 1001
name: 张三
age: 22
gender: 男
stu_name: stu
id: 1002
name: 李四
age: 21
gender: 女
  1. 还有另外一种情况就是返回的结果是xml,那么具体解析需要通过以下方法
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Eric.yue


import json
import xml.sax.handler

class XMLHandler(xml.sax.handler.ContentHandler):
    def __init__(self):
        self.buffer = ""
        self.mapping = {}

    def startElement(self, name, attributes):
        self.buffer = ""

    def characters(self, data):
        self.buffer += data

    def endElement(self, name):
        self.mapping[name] = self.buffer

    def getDict(self):
        return self.mapping


data = '''<?xml version="1.0" encoding="UTF-8"?><note><to>World</to><from>Linvo</from><heading>Hi</heading><body>Hello World!</body></note>'''

xh = XMLHandler()
xml.sax.parseString(data, xh)
ret = xh.getDict()
print json.dumps(ret,indent=4)

输出结果:

{
    "body": "Hello World!", 
    "to": "World", 
    "note": "Hello World!", 
    "from": "Linvo", 
    "heading": "Hi"
}

借鉴:https://mp.weixin.qq.com/s/gYjsPyPmCyoOgXGMF2kc6Q



标签:XML,xml,name,python,gender,self,stu,解析,id
From: https://blog.51cto.com/u_2820398/6320181

相关文章

  • linux中/etc/passwd文件与/etc/shadow文件解析
     在linux操作系统中,/etc/passwd文件中的每个用户都有一个对应的记录行,记录着这个用户的一下基本属性。该文件对所有用户可读。  而/etc/shadow文件正如他的名字一样,他是passwd文件的一个影子,/etc/shadow文件中的记录行与/etc/passwd中的一一对应,它由pwconv命令根据/etc/pas......
  • python datetime时区转换
    比如把格林威治时间转换为上海时间:fromdatetimeimportdatetimeimportpytzprint('格林威治时间:',datetime.now().strftime("%Y-%m-%d_%H-%M-%S"))print('上海时间:',datetime.now().astimezone(pytz.timezone("Asia/Shanghai")).strftime("......
  • Python 多进程之间共享变量
    转载:Python多进程之间共享变量-知乎(zhihu.com)Python多线程之间共享变量很简单,直接定义全局global变量即可。而多进程之间是相互独立的执行单元,这种方法就不可行了。不过Python标准库已经给我们提供了这样的能力,使用起来也很简单。但要分两种情况来看,一种是Process......
  • python类中调用类方法时,报错self参数未填
    转载:(14条消息)python类中调用类方法时,报错self参数未填。_追天一方的博客-CSDN博客又碰到了一个小错误比如一个类如下:classprint_number(object):def__init__(self,string="数字是"):self.string=stringdefprint_(self,ss=3):print("{}:{}".......
  • ifc的解析思路
    IFC标准的解析包括以下几个方面:资源层解析:资源层是IFC标准中最基础的信息层,包含了建筑工程中所需的各种基础信息,如材料、几何、拓扑等。资源层的信息通常是通过定义特性、数量、分类等属性来描述的。核心层解析:核心层定义了IFC标准中信息模型的整体框架,包括工程对象之间的关系......
  • java中使用jep调用python类
    经过调研,目前这应该只有一种调用方式了,那就是使用jep,后来亲测了以下确实是可行,我是使用jep调用了一个python文件中的类,并测试了类的一个方法,可以正常执行,但是具体速度会不会慢很多,我还没有测试。刚开始在调研的时候,说jython也可以调用,但是这个包只支持2.7python,毕竟现在很少有用2......
  • Day 41 41.1 Python中json模块的loadloads方法实战及参数详解
    Python中json模块的load/loads方法实战及参数详解【一】loads方法与load方法的异同在Python中json是一个非常常用的模块,这个主要有4个方法:json.dumpsjson.dumpjson.loadsjson.load这里主要分析讲解一下json的loads和load方法。这两个方法中都是把其他类型......
  • Day 41 41.2 Python中json模块之dumps参数详解
    Python的JSON用法之dumps的各种参数用法(详细)JSON是用于存储和交换数据的语法。JSON(JavaScriptObjectNotation)最初是用JavaScript对象表示法编写的文本,但随后成为了一种常见格式,被包括Python在内的众多语言采用。在使用json方法的时候要记住先引进这个库importjson......
  • oracle中SCN详细解析
    在Oracle数据库中,SCN表示数据库中状态变化的时间点,是一个连续唯一的数字标识符。SCN的类型比较多,本文将会详细介绍控制文件中的SCN、检查点(SCNCheckpoint)、数据文件的起始SCN和终止SCN、归档日志的SCN以及在线日志的SCN,同时描述这些不同类型的SCN之间的关系。控制文件中的SCN在O......
  • Python 设计模式-观察者模式
    观察者模式是一种行为设计模式,它允许你定义一种订阅机制,可以在对象事件发生时通知多个观察者对象。下面是一个简单的Python观察者模式代码示例:classSubject:"""被观察者类,维护观察者列表,并在状态发生改变时通知观察者"""def__init__(self):self._......