Python3.6 多种方式 解析 自定义 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 易于扩展,主要用来传送和存储数据,聚焦的是数据的内容。

二、解析方式

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 使用也很方便。

三、具体实现

test.xml

<?xml version="1.0" encoding="utf-8"?>
<info>
   <intro>Book message</intro>
    <list id='001'>
        <head>bookone</head>
        <name>python check</name>
        <number>001</number>
        <page>200</page>
    </list>

    <list id='002'>
        <head>booktwo</head>
        <name>python learn</name>
        <number>002</number>
        <page>300</page>
    </list>

</info>

3.1 DOM 方式解析

  • minidom.parse(filename):加载读取XML文件
  • doc.documentElement:获取XML文档对象
  • node.getAttribute(AttributeName):获取XML节点属性值
  • node.getElementsByTagName(TagName):获取XML节点对象集合
  • node.childNodes :返回子节点列表。
  • node.childNodes[index].nodeValue:获取XML节点值
  • node.firstChild:访问第一个节点,等价于pagexml.childNodes[0]

返回Node节点的xml表示的文本:

doc = minidom.parse(filename)
doc.toxml('UTF-8')

访问元素属性:

  • Node.attributes[“id”]
  • a.name #就是上面的 “id”
  • a.value #属性的值
import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
root=dom1.documentElement
book={}
booknode=root.getElementsByTagName('list')
for booklist in booknode:
    print '='*20
    print 'id:'+booklist.getAttribute('id')
    print 'head:'+booklist.getElementsByTagName('head')[0].childNodes[0].nodeValue.strip()
    print 'name:'+booklist.getElementsByTagName('name')[0].childNodes[0].nodeValue.strip()
    print 'number:'+booklist.getElementsByTagName('number')[0].childNodes[0].nodeValue.strip()
    print 'page:'+booklist.getElementsByTagName('page')[0].childNodes[0].nodeValue.strip()

输出如下

====================
id:001
head: bookone
name: python check
number: 001
page: 200
====================
id:002
head: booktwo
name: python learn
number: 002
page: 300

3.2 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 结束标签时调用。
# -*- coding: utf-8 -*-

import xml.sax

class BookHandler(xml.sax.ContentHandler):
    def __init__(self):
        self.id = ""
        self.head = ""
        self.name = ""
        self.number = ""
        self.page = ""

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

    # 元素结束调用
    def endElement(self, tag):
        if self.CurrentData == "head":
            print("head:", self.head)
        elif self.CurrentData == "name":
            print("name:", self.name)
        elif self.CurrentData == "number":
            print("number:", self.number)
        elif self.CurrentData == "page":
            print("page:", self.page)
        self.CurrentData = ""

    # 读取字符时调用
    def characters(self, content):
        if self.CurrentData == "head":
            self.head = content
        elif self.CurrentData == "name":
            self.name = content
        elif self.CurrentData == "number":
            self.number = content
        elif self.CurrentData == "page":
            self.page = content

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

输出如下

id: 001
head: bookone
name: python check
number: 001
page: 200
id: 002
head: booktwo
name: python learn
number: 002
page: 300

3.3 ElementTree 解析

  • findall方法将找到指定的所有节点:
import xml.etree.ElementTree
root=xml.etree.ElementTree.parse('book.xml')
book=root.findall('list')
for book_list in book:
    print '='*20
    if  book_list.attrib.has_key('id'):
        print "id:"+book_list.attrib['id']
    for note in book_list:
        print note.tag+':'+note.text
print '='*20

输出如下

====================
id:001
head: bookone
name: python check
number: 001
page: 200
====================
id:002
head: booktwo
name: python learn
number: 002
page: 300
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值