python3基础:操作xml

python3基础:操作xmlXML指的是可扩展标记语言(eXtensibleMarkupLanguage),和json类似也是用于存储和传输数据,还可以用作配置文件。类似于HTML超文本标记语言,但是HTML所有的标签都是预定义的,而xml的标签可以随便定义。XML元素指从开始标签到结束标签的部分(均包括开始和结束)一个元素可以包括:其它元素<aa> <bb></bb&gt…

大家好,又见面了,我是你们的朋友全栈君。

XML 指的是可扩展标记语言(eXtensible Markup Language),和json类似也是用于存储和传输数据,还可以用作配置文件。类似于HTML超文本标记语言,但是HTML所有的标签都是预定义的,而xml的标签可以随便定义。

XML元素

指从开始标签到结束标签的部分(均包括开始和结束)
一个元素可以包括:

  • 其它元素
<aa>
	<bb></bb>
</aa>
  • 属性
<a id=’132’></a>
  • 文本
<a >abc</a>
  • 混合以上所有

XML语法规则

  • 所有的元素都必须有开始标签和结束标签,省略结束标签是非法的。如:
<root>根元素</root>
  • 大小写敏感,以下是两个不同的标签
<Note>this is a test1</Note>
<note>this is a test2</note>
  • xml文档必须有根元素
<note>
 <b>this is a test2</b>
 <name>joy</name>
</note>
  • XML必须正确嵌套,父元素必须完全包住子元素。如:
<note><b>this is a test2</b></note>
  • XML属性值必须加引号,元素的属性值都是一个键值对形式。如:
<book category=" Python"></book>

注意:元素book的category属性值python必须用引号括起来,单引号双引号都可以。如果属性值中包含单引号那么用双引号括起来,如果属性值包含单引号那么外面用双引号括起来。

XML命名规则

名称可以包含字母、数字以及其他字符
名称不能以数字或标点符号开头
名称不能以字母xml或XML开始
名称不能包含空格
可以使用任何名称,没有保留字
名称应该具有描述性,简短和简单,可以同时使用下划线。
避免“-”、“.”、“:”等字符
Xml的注释格式

<!--注释内容-->

Python对XML的解析

常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同,使用场合也不同。python有三种方法解析XML:SAX,DOM和ElementTree

  • DOM(Document Object Model)
    DOM的解析器在解析一个XML文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后利用DOM提供的不同函数来读取该文档的内容和结构,也可以把修改过的内容写入XML文件。由于DOM是将XML读取到内存,然后解析成一个树,如果要处理的XML文本比较大的话,就会很耗内存,所以DOM一般偏向于处理一些小的XML,(如配置文件)比较快。
  • SAX(simple API for XML)
    Python标准库中包含SAX解析器,SAX是用的是事件驱动模型,通过在解析XML过程
    中触发一个个的事件并调用用户定义的回调函数来处理XML文件。
    解析的基本过程:
    读到一个XML开始标签,就会开始一个事件,然后事件就会调用一系列的函数去处理
    一些事情,当读到一个结束标签时,就会触发另一个事件。所以,我们写XML文档入
    如果有格式错误的话,解析就会出错。
    这是一种流式处理,一边读一边解析,占用内存少。适用场景如下:
    1、对大型文件进行处理;
    2、只需要文件的部分内容,或者只需从文件中得到特定信息。
    3、想建立自己的对象模型的时候。
  • ElementTree(元素树)
    ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。

注:因DOM需要将XML数据映射到内存中的树,一是比较慢,二是比较耗内存,而SAX流式读取XML文件,比较快,占用内存少,但需要用户实现回调函数(handler)

xml.dom解析XML

本次先介绍DOM方式操作XML,先建立名为book.xml的文件供后续使用。

<?xml version="1.0" encoding="utf-8" ?>
<!--this is a test about xml.-->
<booklist type="science and engineering">
 <book category="math">
 <title>learning math</title>
 <author>张三</author>
 <pageNumber>561</pageNumber>
 </book>
 <book category="Python">
 <title>learning Python</title>
 <author>李四</author>
 <pageNumber>600</pageNumber>
 </book>
</booklist>

minidom.parse(parse=None,bufsie=None)

函数作用:使用parse解析器打开xml文档,并将其解析为DOM文档,也就是内存中的一棵树,并得到这个对象

doc.documentElement

获取xml文档对象,就是拿到DOM树的根
代码示例:

>>> from xml.dom.minidom import parse
>>> DOMTree=parse(r'book.xml')
>>> type(DOMTree)
<class 'xml.dom.minidom.Document'>
>>> booklist=DOMTree.documentElement
>>> booklist
<DOM Element: booklist at 0x19c0606b340>
doc.toxml(encoding=None)
返回xml的文档内容
>>> booklist=DOMTree.documentElement
>>> print (booklist.toxml())
<booklist type="science and engineering">
 <book category="math">
 <title>learning math</title>
 <author>张三</author>
 <pageNumber>561</pageNumber>
 </book>
 <book category="Python">
 <title>learning Python</title>
 <author>李四</author>
 <pageNumber>600</pageNumber>
 </book>
</booklist>

在这里插入图片描述

node.lastChild

返回元素的最后一个子节点

node.firstChild

返回元素的首个子节点
代码示例:

>>> booklist.lastChild
>>> booklist.firstChild

在这里插入图片描述

getElementsByTagName(name)获取节点元素

获取xml文档中的某个父节点下具有相同节点名的节点对象的集合。返回的是list
代码示例:

from xml.dom.minidom import parse

#minidom解析器打开xml文档并将其解析为内存中的一棵树
DOMTree=parse(r'book.xml')
#获取xml文档对象,就是拿到树的根
booklist=DOMTree.documentElement
#获取booklist对象中所有book节点的list集合
books=booklist.getElementsByTagName('book')
print(books)
print (type(books))
print(books)
print('有%d个book节点'%len(books))
print('*'*40)
print('第一个book节点%s'%booklist.getElementsByTagName('book')[0])
print('*'*40)
print('第一个book节点节点内容%s'%booklist.getElementsByTagName('book')[0].toxml())
print('*'*40)
print('第一个title节点%s'%booklist.getElementsByTagName('title')[0].toxml())

在这里插入图片描述

hasAttribute(name)判断是否包含属性值

代码示例:

from xml.dom.minidom import parse
#minidom解析器打开xml文档并将其解析为内存中的一棵树
DOMTree=parse(r'book.xml')
#获取xml文档对象,就是拿到树的根
booklist=DOMTree.documentElement
print('DOM树的根对象:',booklist)
if booklist.hasAttribute('type'):
      #判断根节点booklist是否有type属性
      print('booklist 元素存在type属性')
else:
      print('booklist 元素不存在type属性!!!')

if booklist.getElementsByTagName('book')[0].hasAttribute('category'):
      #判断第一个book节点是否有category属性
      print('第一个book节点存在category属性')
else:
      print('第一个book节点不存在category属性!!!')

在这里插入图片描述

node.getAttribute(name):获取节点node的属性值

代码示例:‘’‘Node.getAttribute获取节点的属性值’‘’

from xml.dom.minidom import parse
#minidom解析器打开xml文档并将其解析为内存中的一棵树
DOMTree=parse(r'book.xml')
#获取xml文档对象,就是拿到树的根
booklist=DOMTree.documentElement

if  booklist.hasAttribute('type'):
     #判断根节点booklist是否有type属性
      print('booklist 元素存在type属性')
      print ('根节点booklist的type属性值为:',booklist.getAttribute('type'))
else:
      print('booklist 元素不存在type属性!!!')

在这里插入图片描述

node.childNodes:返回节点node下所有的子节点组成的list

代码示例:‘’‘node.childNodes’‘’

from xml.dom.minidom import parse

#minidom解析器打开xml文档并将其解析为内存中的一棵树
DOMTree=parse(r'book.xml')
#获取xml文档对象,就是拿到树的根
booklist=DOMTree.documentElement
#获取booklist对象中所有book节点的list集合
books=booklist.getElementsByTagName('book')

print('第一个book元素的所有子节点:',books[0].childNodes)

在这里插入图片描述

获得标签属性

每一个结点都有它的nodeName,nodeValue,nodeType属性
node.nodeName
node.nodeValue #nodeValue是结点的值,只对文本结点有效
node.nodeType

代码示例:‘’‘获取标签属性’‘’

from xml.dom.minidom import parse
#minidom解析器打开xml文档并将其解析为内存中的一棵树
DOMTree=parse(r'movie.xml')
#获取xml文档对象,就是拿到树的根
collection=DOMTree.documentElement
print ('collection属性',collection.nodeName,collection.nodeValue,collection.nodeType)
      
#获取所有的movies节点
movies=collection.getElementsByTagName('movie')

#遍历集合,打印所有节点的nodename/nodeValue/nodeType
for movie in movies:
      print ("*******************movie*******************")
      for node in movie.childNodes:
            print (node.nodeName,node.nodeValue,node.nodeType)

获取节点文本值

代码示例:‘’‘获取节点文本值’‘’

from xml.dom.minidom import parse
#minidom解析器打开xml文档并将其解析为内存中的一棵树
DOMTree=parse(r'book.xml')
#获取xml文档对象,就是拿到树的根
booklist=DOMTree.documentElement

if booklist.hasAttribute('type'):
      #判断根节点booklist是否有type属性,有则获取并打印属性值
      print('Root element is ',booklist.getAttribute('type'))

#获取booklist对象中所有的book节点的list集合
books=booklist.getElementsByTagName('book')
print('book节点的个数为:',len(books))
print('book节点的个数为:',books.length)
print ()

for book in books:
      print ("*******************book*******************")
      if book.hasAttribute('category'):
             print ('category is ',book.getAttribute('category'))
      #根据节点名title/author/pageNumber得到这些节点的集合list
      title=book.getElementsByTagName('title')[0]
      author=book.getElementsByTagName('author')[0]
      pageNumber=book.getElementsByTagName('pageNumber')[0]

      print ('title is ',title.childNodes[0].data)
      print ('author is ',author.childNodes[0].data)
      print ('pageNumber is ',pageNumber.childNodes[0].data)

在这里插入图片描述

node.hasChildNodes():判断是否有子节点

代码示例:‘’‘node .hasChildNodes()’‘’

from xml.dom.minidom import parse

#minidom解析器打开xml文档并将其解析为内存中的一棵树
DOMTree=parse(r'book.xml')
#获取xml文档对象,就是拿到树的根
booklist=DOMTree.documentElement
if booklist.hasAttribute('type'):
      #判断根节点booklist是否有type属性,有则获取并打印属性值
      print('Root element is ',booklist.getAttribute('type'))

#获取booklist对象中所有的book节点的list集合
books=booklist.getElementsByTagName('book')
print('book节点的个数为:',books.length)
print ()

if books[0].hasChildNodes():
      print('存在子节点:',books[0].childNodes)
else:
       print('不存在子节点')

在这里插入图片描述

主要方法总结:

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 #属性的值

root.nodeName/root.tagName:节点的名称
root.nodeValue:节点的值,文本节点才有值,其它节点返回的是None
root.nodeType:节点的类型
NodeType Named Constant
1 ELEMENT_NODE2 ATTRIBUTE_NODE3 TEXT_NODE4 CDATA_SECTION_NODE5 ENTITY_REFERENCE_NODE6 ENTITY_NODE7 PROCESSING_INSTRUCTION_NODE8 COMMENT_NODE9 DOCUMENT_NODE10 DOCUMENT_TYPE_NODE11 DOCUMENT_FRAGMENT_NODE12 NOTATION_NODE

练习1:读取xml文件写入excel

代码示例:
‘’‘将xml文件写入到文件中’‘’
from xml.dom.minidom import parse
from openpyxl import Workbook

DOMTree=parse(r’book.xml’)
booklist=DOMTree.documentElement

type_name=booklist.getAttribute(‘type’)

#获取第二个book对象的内容
book=booklist.getElementsByTagName(‘book’)[1]
book_name=book.getAttribute(‘category’)
title=book.getElementsByTagName(‘title’)[0].childNodes[0].data
author=book.getElementsByTagName(‘author’)[0].childNodes[0].data
pageNumber=book.getElementsByTagName(‘pageNumber’)[0].childNodes[0].data

wb=Workbook()
ws=wb.active
ws.append([book_name,title,author,pageNumber])
wb.save(r’book.xlsx’)

练习2:xml.dom解析xml的一个实例

xml文件内容:

<?xml version="1.0" encoding="utf-8" ?>
<!--this is a test about 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>

代码示例:‘’‘xml.dom解析xml的一个实例’‘’

from xml.dom.minidom import parse
#minidom解析器打开xml文档并将其解析为内存中的一棵树
DOMTree=parse(r'move.xml')
#获取xml文档对象,就是拿到树的根
collection=DOMTree.documentElement

if collection.hasAttribute('shelf'):
       #判断根节点collection是否有shelf属性,有则获取并打印属性值
      print('Root element is ',collection.getAttribute('shelf'))
      
#获取所有的movies节点
movies=collection.getElementsByTagName('movie')

#遍历集合,打印每部电影的详细信息
for movie in movies:
      print ("*******************movie*******************")
      my_list=[]
      if movie.hasAttribute('title'):
            print ('title is ',movie.getAttribute('title'))

            
      for node in movie.childNodes:
            my_list.append (node.nodeName)
      type=movie.getElementsByTagName('type')[0]
      print ('type is ',type.childNodes[0].data)
      format=movie.getElementsByTagName('format')[0]
      print ('format is ',format.childNodes[0].data)

      if 'year' in my_list:
            year=movie.getElementsByTagName('year')[0]
            print ('year is ',year.childNodes[0].data)
      
      rating=movie.getElementsByTagName('rating')[0]
      print ('rating is ',rating.firstChild.data)
      
      stars=movie.getElementsByTagName('stars')[0]
      print ('stars is ',stars.childNodes[0].data)
      
      description=movie.getElementsByTagName('description')[0]
      print ('description is ',description.childNodes[0].data)

在这里插入图片描述

xml.dom创建XML文件

创建步骤:
1.创建XML空白文档
2.产生根对象
3.向根对象中加入数据
4.将xml内存对象写入文件

minidom.Document()创建xml空白文档

该方法用于创建一个空白的xml文档对象,并返回这个doc对象。每个xml文档都是一个Document对象,代表着内存中的DOM树
代码示例:‘’‘minidom.Document()创建xml空白文档’‘’

import xml.dom.minidom
#在内存中创建一个空的文档
doc=xml.dom.minidom.Document()
print(doc)

在这里插入图片描述

doc.createElement(tagName)

生成XML文档节点。参数表示待生成的节点名称
代码示例:

import xml.dom.minidom
#在内存中创建一个空的文档
doc=xml.dom.minidom.Document()
#创建一个根节点对象
root=doc.createElement('Manager')
print('添加的xml标签为:',root.tagName)

在这里插入图片描述

node.setAttribute(attname,value)

函数作用:给节点添加属性-值对(attribute)
参数说明
attname:属性的名称
value:属性的值
代码示例:‘’‘node.setAttribute(attname,value)’‘’

import xml.dom.minidom
#在内存中创建一个空的文档
doc=xml.dom.minidom.Document()
#创建一个根节点对象
root=doc.createElement('Manager')
print('添加的xml标签为:',root.tagName)

#给根节点添加属性
root.setAttribute('name','kongsh')
value=root.getAttribute('name')
print('root元素的name属性为:',value)

在这里插入图片描述

doc.createTextNode(data)

给叶子节点添加文本节点
代码示例:‘’‘doc.createTextNode(data)’‘’

import xml.dom.minidom
#在内存中创建一个空的文档
doc=xml.dom.minidom.Document()
#创建一个根节点对象
root=doc.createElement('test')
print('添加的xml标签为:',root.tagName)

#给根节点添加属性
root.setAttribute('name','python')
value=root.getAttribute('name')
print('root元素的name属性为:',value)

#给根节点添加一个叶子节点
ceo=doc.createElement('person')
#给叶子节点ceo设置一个文本节点,用于显示文本内容
ceo.appendChild(doc.createTextNode('kongsh'))
print (ceo.tagName)
print ("给叶子节点添加文本节点成功")

在这里插入图片描述

parent.appendChild(childNode)

把子节点childNode添加到父节点parent中
代码示例:‘’‘parent.appendChild(childNode)’‘’

import xml.dom.minidom
#在内存中创建一个空的文档
doc=xml.dom.minidom.Document()
#创建一个根节点companys对象
root=doc.createElement('companys')
print('添加的xml标签为:',root.tagName)

#给根节点添加属性
root.setAttribute('name','公司信息')
#将根节点添加到文档对象中
doc.appendChild(root)

#给根节点添加一个叶子节点
company=doc.createElement('gloryroad')
#叶子节点下再嵌套叶子节点
name=doc.createElement('name')
#给节点添加文本节点                  
name.appendChild(doc.createTextNode('光荣之路'))

ceo=doc.createElement('CEO')
ceo.appendChild(doc.createTextNode('吴老师'))
#将各叶子节点添加到父节点company中
company.appendChild(name)
company.appendChild(ceo)
#将company节点添加到根节点companys中
root.appendChild(company)
print (doc.toxml())

在这里插入图片描述

doc.writexml():生成xml文档

函数作用:用于将内存中的xml文档树写入到文件中,并保存到本地磁盘。只有调用该方法后,才能将上面创建的存在于内存中的xml文档写入本地硬盘中,这时才能看到新建的xml文档
语法
writexml(file,indent=‘’,addindent=‘’,newl=‘’,endocing=None)
参数说明
file:要保存为的文件对象名
indent:根节点的缩进方式
allindent:子节点的缩进方式
newl:针对新行,指明换行方式
encoding:保存文件的编码方式

代码示例:‘’‘writexml(file,indent=’‘,addindent=’‘,newl=’‘,endocing=None)’‘’

import codecs
import xml.dom.minidom
#在内存中创建一个空的文档
doc=xml.dom.minidom.Document()
#创建一个根节点companys对象
root=doc.createElement('companys')
print('添加的xml标签为:',root.tagName)

#给根节点添加属性
root.setAttribute('name','公司信息')
#将根节点添加到文档对象中
doc.appendChild(root)

#给根节点添加一个叶子节点
company=doc.createElement('gloryroad')
#叶子节点下再嵌套叶子节点
name=doc.createElement('name')
#给节点添加文本节点                  
name.appendChild(doc.createTextNode('光荣之路'))

ceo=doc.createElement('CEO')
ceo.appendChild(doc.createTextNode('吴老师'))
#将各叶子节点添加到父节点company中
company.appendChild(name)
company.appendChild(ceo)
#将company节点添加到根节点companys中
root.appendChild(company)

# 通过codecs.open函数,指定编码方式
fp=open(r'company.xml','w',encoding='utf-8')
#将内存中的xml写入到文件
doc.writexml(fp,indent='',addindent='\t',newl='\n',encoding='utf-8')
fp.close()
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/158211.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号