XML简介
1.指可扩展标记语言(extensible markup language)
2.是一种标记语言
3.被设计用于结构化、存储和传输数据
4.没有像html那样具有预定义标签,需要程序员自定义标签
5.XML被设计为具有自我描述性,并且是W3C的标准
xml文档
XML文档形成了一种树结构,它从“根部”开始,然后扩展到“树 枝”。 XML文档必须包含根元素,该元素是所有其他元素的父元素,文档中的所有元素形成了一棵文档树,这棵树从根开始,并扩展到树的最顶端,并且所有的元素都可以有子元素。
父元素拥有子元素,相同层级上的子元素成为同胞(兄弟或姐妹)。 XML中所有子元素都可以有文本内容和属性,类似于HTML
xml基础知识介绍
xml元素
XML的元素是指从开始标签直到结束标签的部分(均包括开始结束)。
一个元素可以包含: 名字、属性、文本、或混合以上
xml语法规则
1.所有的XML元素都必须有一个开始标签和结束标签,省略结束标签是非法的
<root>content</root>
2.XML标签对大小写敏感
<note>this is a test1</note>
<Note>this is a test2</Note>
3.XML一定要有一个根元素,最大的一层
<note>
<b>this is a test1</b>
<name>joy</name>
</note>
3.XML必须正确嵌套,父元素必须完全包住子元素
<note><b>this is a test2</b></note>
4.XML属性值必须加引号,元素的属性值都是一个键值对的形式
<book category="python"></book>
需要注意的是:book元素中的属性category的值是python必须用引号引起来,使用单引号和 双引号都可以,但是如果属性值本身包含双引号,外层就必须使用单引号;但 如果包含了单引号,外层必须使用双引号
xml命名规则
可以包含字母、数字以及其他字符
名称不能以数字或标点符号开头
名称不能以字母XML或xml开始
名称不能包含空格
名称可以使用任何名称,没有保留字
名称应该具有描述性,简短和简单,可以同时使用下划线
避免“-”、“.”、“:”等字符
XML注释格式为:<!--注释内容-->
CDATA
指的是不应由XML解析器进行解析的文本数据。
CDATA固定语法格式:<![CDATA[“我们自己的代码"]]>
Python解析XML三种方法
1、SAX(simple API for XML)
Python标准库中包含SAX解析器,SAX是用的是事件驱动模型,通过在解析XML过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。
解析的基本过程: 读到一个XML开始标签,就会开始一个事件,然后事件就会调用一系列的函数去处理一些事情,当读到一个结束标签时,就会触发另一个事件。所以,我们写XML文档入如果有格式错误的话,解析就会出错。这是一种流式处理,一边读一边解析,占用内存少。
2.DOM(Document Object Model)
DOM是Document Object Model的简称,它是以对象树来表示一个XML文档的方法,使用它的好处就是你可以非常灵活的在对象中进行遍历。将XML数据在内存中解析成一个树,通过对树的操作来操作XML。由于DOM是将XML读取到内存,然后解析成一个树,如果要处理的XML文本比较大的话,就会很耗内存,所以DOM一般偏向于处理一些小的XML,(如配置文件)比较快。
3.ElementTree(Object Model)
ElementTree就像一个轻量级的DOM,具有方便而友好的API。代码的可用性好、速度快、消耗内存少。可以认为是对DOM的改进。
注意:DOM需要将XML数据映射到内存中的树,一是比较慢,而是比较耗内存,而 SAX流式读取XML文件,比较快,占内存少,但需要用户实现回调函数(handler)。
xml.dom解析xml思路
一次性读取整个文档,把文档中的所有元素保存在内存中的一个树结构里,之后利用DOM提供的不同函数来读取该文档的内容和结构,也可以把修改过的内容写入XML文件
minidom.parse(parser=None,bufsize=None)
该函数的作用是使用parse解析器打开xml文档,并将其解析为DOM文档,也就是内存中的一棵树,并得到这个DOM对象
#从xml.dom.minidom模块引入解析器parse
from xml.dom.minidom import parse
#minidom解析器打开xml文档并将其解析为内存中的一棵树
DOMTree=parse(r"C:\Users\zhigang\Desktop\book.xml")
print (type(DOMTree))
doc.documentElement:获取xml文档对象,就是拿到DOM树的根
doc. toxml():获取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>
代码示例:
#encoding:utf-8
#从xml.dom.minidom模块引入解析器parse
from xml.dom.minidom import parse
#minidom解析器打开xml文档并将其解析为内存中的一棵树
DOMTree=parse(r"C:\Users\zhigang\Desktop\book.xml")
print (type(DOMTree))
#获取xml文档对象,就是拿到树的根
booklist=DOMTree.documentElement
print ("DOM树的根对象%s" % booklist)
print ("*"*50)
print ("xml文档内容: \n%s" % DOMTree.toxml())
print ("*"*50)
if booklist.hasAttribute("type"):
#判断根节点booklist是否有type属性
print ("booklist元素存在type属性")
else:
print ("booklist元素不存在type属性")
输出结果为:
node.getAttribute(attname):获取节点node的某个属性的值
from xml.dom.minidom import parse
#minidom解析器打开xml文档并将其解析为内存中的一棵树
DOMTree=parse(r"C:\Users\zhigang\Desktop\book.xml")
#获取xml文档对象,就是拿到树的根
booklist=DOMTree.documentElement
print ("DOM树的根对象%s" % booklist)
print ("*"*50)
if booklist.hasAttribute("type"):
#判断根节点booklist是否有type属性
print ("Root element is",booklist.getAttribute("type"))
else:
print ("booklist元素不存在type属性")
输出结果为:
node.getElementsByTagName(name):获取xml文档中某个父节点下具有相同节点名的节点对象集合,是一个list对象
#从xml.dom.minidom模块引入解析器parse
from xml.dom.minidom import parse
#minidom解析器打开xml文档并将其解析为内存中的一棵树
DOMTree=parse(r"C:\Users\zhigang\Desktop\book.xml")
#获取xml文档对象,就是拿到树的根
booklist=DOMTree.documentElement
print ("DOM树的根对象%s" % booklist)
print ("*"*50)
#获取booklist对象中所有book节点的list集合
books=booklist.getElementsByTagName("book")
print (type(books))
print (books)
authors=booklist.getElementsByTagName("author")
print (type(authors))
print (authors)
输出结果为:
node.childNodes:返回节点node下所有子节点组成的list
from xml.dom.minidom import parse
DOMTree=parse(r"C:\Users\zhigang\Desktop\book.xml")
booklist=DOMTree.documentElement
print ("DOM树的根对象%s" % booklist)
print ("*"*50)
#获取booklist对象中所有book节点的list集合
books=booklist.getElementsByTagName("book")
print (type(books))
print (books[0].childNodes)
authors=booklist.getElementsByTagName("author")
print (type(authors))
print (authors)
print (authors[0].childNodes)
输出结果为:
tagName取标签节点;
from xml.dom.minidom import parse
DOMTree=parse(r"C:\Users\zhigang\Desktop\book.xml")
#获取xml文档对象,就是拿到树的根
booklist=DOMTree.documentElement
print ("DOM树的根对象%s" % booklist)
print ("*"*50)
#获取booklist对象中所有book节点的list集合
books=booklist.getElementsByTagName("book")
print ((books))
#返回节点node下所有子节点组成的list
print (books[1].childNodes)
d={}
for i in range(1,6,2):
tag_name=books[1].childNodes[i].tagName #标签节点
d[tag_name]=books[1].childNodes[i].childNodes[0].data #文本节点
print (d)
for k,v in d.items():
print (k,v)
输出结果为:
data获取节点文本值:
from xml.dom.minidom import parse
DOMTree=parse(r"C:\Users\zhigang\Desktop\book.xml")
#获取xml文档对象,就是拿到树的根
booklist=DOMTree.documentElement
print ("DOM树的根对象%s" % booklist)
print ("*"*50)
#获取booklist对象中所有book节点的list集合
books=booklist.getElementsByTagName("book")
print ("共有%s本书" % len(books))
for book in books:
print ("*"*30)
if book.hasAttribute("category"):
print (book.getAttribute("category"))
title=book.getElementsByTagName("title")[0]
print (title.childNodes[0].data)
author=book.getElementsByTagName("author")[0]
print (author.childNodes[0].data)
pageNumber=book.getElementsByTagName("pageNumber")[0]
print (pageNumber.childNodes[0].data)
输出结果为:
node.hasChildNodes():判断节点node下是否有叶子节点,如果有返回True,否则返回False
from xml.dom.minidom import parse
DOMTree=parse(r"C:\Users\zhigang\Desktop\book.xml")
#获取xml文档对象,就是拿到树的根
booklist=DOMTree.documentElement
#print ("DOM树的根对象%s" % booklist)
#print ("*"*50)
#获取booklist对象中所有book节点的list集合
books=booklist.getElementsByTagName("book")
print (books[0])
if books[0].hasChildNodes():
print ("存在叶子节点:\n",books[0].childNodes)
else:
print ("不存在叶子节点")
输出结果为:
xml.dom创建xml文件
创建xml文件的步骤如下:
1.创建xml空文档
2.产生根对象
3.往根对象里加数据
4.把xml内存对象写到文件
创建xml空白文档:minidom.Document()
该方法用于创建一个空白的xml文档对象,并返回这个doc对象。每个xml文档都是一个Document对象,代表着内存中的DOM树
import xml.dom.minidom
#在内存中创建一个空的文档
doc=xml.dom.minidom.Document()
#print (doc)
创建xml文档根节点:doc.createElement(tagName),生成xml文档节点,参数表示要生成节点的名称
import xml.dom.minidom
#在内存中创建一个空的文档
doc=xml.dom.minidom.Document()
print (doc)
root=doc.createElement("Managers")
print ("添加的xml标签为:",root.tagName)
添加节点属性:node.setAttribute(attname,value)该方法表示给节点添加属性值对 attname:属性的名称 value:属性的值
import xml.dom.minidom
doc=xml.dom.minidom.Document()
print (doc)
root=doc.createElement("Managers")
print ("添加的xml标签为:",root.tagName)
root.setAttribute("company","XX科技")
value=root.getAttribute("company")
print ("root元素的company属性值为:",value)
输出结果为:
添加文本节点doc.createTextNode(data):给叶子节点添加文本节点
import xml.dom.minidom
#在内存中创建一个空的文档
doc=xml.dom.minidom.Document()
print (doc)
#创建一个根节点managers对象
root=doc.createElement("Managers")
print ("添加的xml标签为:",root.tagName)
#给根节点root添加属性
root.setAttribute("name","xx科技")
value=root.getAttribute("name")
print ("root元素的company属性值为:",value)
#给根节点添加一个叶子节点
ceo=doc.createElement("CEO")
#给叶子节点name设置一个文本节点,用于显示文本内容
ceo.appendChild(doc.createTextNode("zhigang"))
print(ceo.tagName)
print ("给叶子节点添加文本节点成功")
添加子节点:doc/parentNode.appendChild(node) 将节点node添加到文档对象doc作为文档树的根节点或者添加到父节点parentNode下作为其字节点
import xml.dom.minidom
#在内存中创建一个空的文档
doc=xml.dom.minidom.Document()
#创建一个根节点companys对象
root=doc.createElement("companys")
root.setAttribute("name","公司信息")
#将根节点添加到文档对象中
doc.appendChild(root)
#给根节点添加一个叶子节点
company=doc.createElement("glory")
#叶子节点下再嵌套叶子节点
name=doc.createElement("Name")
#给节点添加文本节点
name.appendChild(doc.createTextNode("光荣"))
ceo=doc.createElement("CEO")
ceo.appendChild(doc.createTextNode("志刚"))
#将各叶子节点添加到父节点company中,然后将company添加到根节点companys中
company.appendChild(name)
company.appendChild(ceo)
root.appendChild(company)
print (doc.toxml())
生成xml文档:doc.writexml(writer,indent="",addindent="",newl="",encoding=None) 该方法用于将内存中xml文档树写入文件中,并保存到本地磁盘
weriter:要写的目标文件的文件对象à保存在哪个文件中
indent:指明根节点缩进方式
addindent:指明子节点缩进方式
newl:针对新行,指明换行方式
encoding:指明所写xml文档的编码
import xml.dom.minidom
import codecs #编码解码器,自动保存utf-8格式
#在内存中创建一个空的文档
doc=xml.dom.minidom.Document()
root=doc.createElement("users")
root.setAttribute("company","融宝员工")
user1=doc.createElement("userinfo")
name=doc.createElement("Name")
name.appendChild(doc.createTextNode("志刚"))
age=doc.createElement("Age")
age.appendChild(doc.createTextNode("25"))
user1.appendChild(name)
user1.appendChild(age)
root.appendChild(user1)
doc.appendChild(root)
print (doc.toxml())
#生成xml文档
fp=codecs.open(r"C:\Users\zhigang\Desktop\rongbao","w","utf-8")
doc.writexml(fp,indent="",addindent="\t",newl="\n",encoding="utf-8")
fp.close()