python进阶(十七)xml(下)
1、XML简介
xml用到的地方:tomcat配置文件
1) xml 指可扩展标记语言(Extensible Markup Language)
2) xml 被设计用于结构化、存储和传输数据
3) xml 是一种标记语言,很类似于HTML
4) xml 没有像HTML那样具有预定义标签,需要程序员自定义标签
5) xml 被设计为具有自我描述性,并且是W3C的标准。
2、xml和html的区别:
html是xml的一种特例。html里面的标签全都是已经预定义好的,都是有含义的。
xml的数据存储和显示是分开的,存储一个文件,显示一个文件,xml不需要标签,可以自定义。
xml:
<bookstore>
<book>
<name>技术指南</name>
</book>
</bookstore>
如果将以上内容放进浏览器中,浏览器中可以看到,但是不能像html显示各种样式。
如果将以上xml也能作为网页显示,如何实现?
3、html5实例:
网址链接:
http://www.w3school.com.cn/tiy/t.asp?f=html5_video_all
代码:
<!DOCTYPE HTML>
<html>
<body>
<video width="320" height="240" controls="controls">
<source src="/i/movie.ogg" type="video/ogg">
<source src="/i/movie.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</body>
</html>
html5比html4的区别就是多了很多标签
<h1>我的第一个标题</h1>
<p>我的死一个段落。</p>
<div>块
<title>标题
4、AJAX
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下。
实际用处:比如,注册页面,用户名还未提交,就提示该用户名已被使用
该技术的好处:不用刷新页面,重新加载页面要3s,而AJAX需要几十-几百毫秒。
异步传输:5个步骤,谁先执行都可以,没有先后顺序,可以并发
同步传输:按照顺序传输,1,2,3,4,5
5、CMS(content management system,新闻发布系统)
6、Apache和tomcat的区别:
Apache只能做静态网页的显示。
tomcat既能动态也能静态
静态网页:网页一旦生成好,网页是不变的。访问的内容是一样的。
动态网页:是根据你的请求数据和服务器的处理规则实时生成的网页。
7、XML文档(树结构)
XML文档形成了一种树结构,它从”根部开始”,然后扩展到“树枝”。
XML文档必须包含根元素,该元素是所有其他元素的父元素,文芳中的所有元素形成了一棵文档树,这棵树从根开始,并扩展到树的最顶端,并且所有的元素都可以有子元素。
<root>
<child>
<subchild>...</subchild>
</child>
</root>
父元素拥有子元素,相同层级上的子元素成为同胞(兄弟或姐妹)。XML中所有子元素都可以有文本内容和属性,类似于HTML.
8、XML基础知识介绍
1) XML元素
XML元素是指开始标签到结束标签的部分(均包括开始结束)。
一个元素可以包含:
1. 其他元素
2. 文本
3. 属性
4. 或混合以上所有
<!-- Edited with XML Spy v2007 (http://www.altova.com) --> #xml注释
<catalog> #根元素
<cd> #子标签
<title>Empire Burlesque</title> # Empire Burlesque文本节点,和空格也是文本节点,<>内的内容是element 节点
<artist>Bob Dylan</artist> #<title>为标签
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>...</cd>
</catalog>
<cd class = "classic"> #class = "classic"为属性,做辅助说明的
<a href = "http://www.souhu.com">souhu</a>
# href = http://www.souhu.com标签里面的内容,以=显示的叫做属性
#点击souhu这个蓝字,会跳转到http://www.souhu.com这个网页中
2) XML语法规则
1. 所有的XML元素都必须有一个开始标签和结束标签,省略结束标签是非法的。如:
<root>content</root>
2. html可以少一个标签,因为浏览器会自动纠错,浏览器怎么解析html都不会崩溃。如果少一个标签,也可以解析,不过解析的内容可能和预期有差异。
<title>光荣之路
3. XML标签对大小写敏感;比如:下面时两个不同的标签
<Note>this is a test1<Note>
<note>this is a test2<note>
4. XML文档必须有根元素。如:
<note>
<b>this is a test2</b>
<name>joy</name>
</note>
5. XML必须正确嵌套,父元素必须完全包住子元素。如:
<note><b>this is a test2</b><name>joy</name></note>
6. XML属性值必须加引号,元素的属性值都是一个键值对形式。如:
<book catgory = “Python”></book>
注意:
book元素中的属性category的值是Python必须用引号引起来,使用单引号和双引号都可以,但是如果属性值本身包含双引号,外层必须使用单引号;但如果包含了单引号,外层必须使用双引号。
9、XML命名规则
XML元素必须遵循以下命名规则:
1)名称可以包含字母、数字以及其他字符
2)名称不能以数字或标点符号开头
3)名称不能以字母xml或XML开始
4)名称不能包含空格
5)可以使用任何名称,没有保留字
6)名称应该具有描述性,简短和简单,可以同时使用下划线。
7)避免-、.、:等字符
8)XML的注释格式为:<! -- 注释内容 --> #和html的注释一样。
#注释的内容不会作为浏览器显示的内容,也不会作为XML解析的内容
10、CDATA
CDATA(Unparsed Character Data)指的是不应由XML解析器进行解析的文本数据。
XML解析器会将“<”(新元素的开始)和”&”(字符实体的开始)解析成具有特殊汉含义的字符。当代码中含有大量的“<”和”&”符号,可以将脚本定义为CDATA来避免这个问题,因为XML文档中的所有文本均会被解析器解析,只有CDATA部分中的所有的内容会被XML解析器忽略。
<![CDATA[“我们自己的代码”]]>
注意:CDATA部分不能包含字符串”]]>”,并且”]]>”之间不能有空格或折行等字符,如果包含了,会以为是CDATA的结束。也不允许嵌套CDATA部分。
<script>
<![CDATA[
function test(x,y)
{ if (x<0 &&y<0) then
{
return 0;
}
else
{
return 1:
}
]]>
</script>
11、Python解析XML三种方法
1)SAX(simple API for XML)
Python标准库中包含SAX解析器,SAX是用的是事件驱动模型,通过在解析XML过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。
解析的基本过程:
读到一个XML开始标签,就会开始一个事件,然后事件就会调用一系列的函数去处理一些事情,当读到一个结束标签时,就会触发另一个事件。所以,我们写XML文档如果有格式错误的话解析就会出错。
这是一种流式处理,一边读一边解析,占用内存少,但速度慢。
2) DOM(Document Object Model)
DOM它是以对象树来表示一个XML文档的方法,使用它的好处就是你可以非常灵活的在对象中进行遍历。
将XML数据在内存中解析成一个树,通过对树的操作来操作XML.
由于DOM是将XML读取到内存,然后解析成一个树,如果要处理的XML文件比较大的话,就会很耗内存,所以DOM一般偏向于处理一些小的XML,(如配置文件)比较快
占内存,但是速度快。--建议这种,因为xml现在普遍挺小,内存已经不是瓶颈。
3) ElementTree(Object Model)
ElementTree就像一个轻量级的DOM,具有方便而友好的API.代码的可用性好、速度快,消耗内存少。可以认为是对DOM的改进。
支持XPATH,定位元素的一种方式。自动化定位元素的一种方式。
12、Xml.dom解析xml
xml.dom解析xml的思路:
一个DOM的解析器在解析一个XML文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后利用DOM提供的不同函数来读取该文档的内容和结构,也可以把修改过的内容写入XML文件。
<?xml version="1.0" encoding="utf-8" ?> #xml文件头
<!--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>
#以上是book.xml文档的内容
13、xml.dom解析xml常用API
1) minidom.parse(parser=None,bufsize=None)
from xml.dom.minidom import parse #从xml.dom.minidom模块引入解析器parse
DOMTree = parse(r"e:\book.xml")
#minidom解析器打开xml文档并将其解析为内存中的一棵树
print(type(DOMTree))
#<class \'xml.dom.minidom.Document\'> #xml的document对象
#minidom.parse(parser=None,bufsize=None)
#该函数的作用是使用parse解析器打开XML文档,并将其解析为DOM文档,也就是内存中的一棵树,并得到这个DOM对象。
2) doc.documentElement:获取xml文档对象,就是拿到DOM树的根
>>> from xml.dom.minidom import parse
>>> DOMTree = parse(r"e:\book.xml")
>>> booklist = DOMTree.documentElement
>>> print(booklist)
<DOM Element: booklist at 0x28471659b90> #booklist是根节点
3) doc.toxml:获取xml文本内容
>>> print(DOMTree.toxml)
<bound method Node.toxml of <xml.dom.minidom.Document object at 0x000002847165AA08>>
>>> print(DOMTree.toxml()) #将xml中的内容除了根节点的内容都打印一下
<?xml version="1.0" ?><!--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>
>>>
4) has Attribute:判断是否包含属性
>>> from xml.dom.minidom import parse
>>> DOMTree = parse(r"e:\book.xml") #minidom解析器打开xml文档并将其解析为内存中的一棵树
>>> booklist = DOMTree.documentElement #获取xml文档对象,就是拿到树的根
>>> print(u"DOM树的根对象:", booklist)
#DOM树的根对象: <DOM Element: booklist at 0x28471659af8>
>>> if booklist.hasAttribute("type"): #判断根节点booklist是否有type属性
... print(u"booklist元素存在type属性")
... else :
... print(u"booklist元素不存在type属性")
...
booklist元素存在type属性
>>>
5) node.getAttrbute:获取节点node的某个属性值
>>> from xml.dom.minidom import parse
>>> DOMTree = parse(r"e:\book.xml") #minidom解析器打开xml文档并将其解析为内存中的一棵树
>>> booklist = DOMTree.documentElement #获取xml文档对象,就是拿到树的根
>>> print(u"DOM树的根对象:", booklist)
#DOM树的根对象: <DOM Element: booklist at 0x284716595a0>
>>> if booklist.hasAttribute("type"): #判断根节点booklist是否有type属性
... print(u"Root element is",booklist.getAttribute("type"))
...
Root element is science and engineering
6) node.getElementsByTagName(name):获取节点元素
获取XML文档中某个父节点下具有相同节点名的节点对象集合,是一个list对象。
>>> from xml.dom.minidom import parse
>>> DOMTree = parse(r"e:\book.xml") #minidom解析器打开xml文档并将其解析为内存中的一棵树
>>> booklist = DOMTree.documentElement #获取xml文档对象,就是拿到树的根
>>> print(u"DOM树的根对象:", booklist)
#DOM树的根对象: <DOM Element: booklist at 0x28471513c28>
>>> books = booklist.getElementsByTagName("book") #获取根节点下标签是book的
>>> print(type(books)) #节点对象,该返回值是个list
<class \'xml.dom.minicompat.NodeList\'>
>>> print(books)
[<DOM Element: book at 0x28471513a60>, <DOM Element: book at 0x28471513638>]
>>> print(books[0])
<DOM Element: book at 0x28471513a60>
#上面解析xml的程序中,getElementsByTagName()函数返回的是同一父节点下所有同级(即兄弟节点)节点中相同标签的集合,这是一个list对象,所以可以使用list序列所有操作。这个时候,我们可以通过索引去拿相应的节点,也可以使用节点名称去拿相应的节点,推荐第二种方法,准确。也可以循环遍历整个返回的list。
注意:
就算某个父节点下没有同名的节点,该方法返回的仍是一个list,只是此时的list为空。
7) node.childNodes:返回节点node下所有子节点组成的list
>>> from xml.dom.minidom import parse
>>> DOMTree = parse(r"e:\book.xml") #minidom解析器打开xml文档并将其解析为内存中的一棵树
>>> booklist = DOMTree.documentElement #获取xml文档对象,就是拿到树的根
>>> print(u"DOM树的根对象:", booklist)
#DOM树的根对象: <DOM Element: booklist at 0x284716595a0>
>>> books = booklist.getElementsByTagName("book")#返回父节点下标签为book的节点
>>> print(books[0].childNodes) #返回第一个book节点下的所有的子节点
[<DOM Text node "\'\n\'">, <DOM Element: title at 0x28471513898>, <DOM Text node "\'\n\'">, <DOM Element: author at 0x284715139c8>, <DOM Text node "\'\n\'">, <DOM Element: pageNumber at 0x28471513930>, <DOM Text node "\'\n\'">]
#<DOM Text node "\'\n\'">是换行,如果不想取换行,拿到所有的子节点,不要文本节点,如何做?
>>> print((books[0].childNodes)[1::2]) #使用切片实现
[<DOM Element: title at 0x28471513898>, <DOM Element: author at 0x284715139c8>, <DOM Element: pageNumber at 0x28471513930>]
8) 获取节点文本值重要!!
1.
from xml.dom.minidom import parse #从xml.dom.minidom模块引入解析器parse
DOMTree =
parse(r"e:\book.xml") #minidom解析器打开xml文档并将其解析为内存中的一棵树
print(type(DOMTree))
<class
\'xml.dom.minidom.Document\'>
booklist = DOMTree.documentElement
print(booklist)
<DOM
Element: booklist at 0x23b6dba2b90>
print("*"*30)
******************************
books = booklist.getElementsByTagName("book")
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) #标签值(文本节点)对于标签来说是一个子节点
{\'title\':
\'learning Python\', \'author\': \'李四\', \'pageNumber\': \'600\'}
for k,v in d.items():
print(k,v)
title learning Python
author 李四
pageNumber 600
.data读取文本节点的值,.data是文本对象的属性,必须是文本对象才可用.data
.tagname读取标签值
element节点在<>中,文本节点是看不见的换行和文字内容
2.
import xml.dom.minidom
from xml.dom.minidom import parse
DOMTree =
xml.dom.minidom.parse(r"e:\book.xml") #minidom解析器打开xml文档并将其解析为内存中的一棵树
booklist = DOMTree.documentElement #获取xml文档对象,就是拿到树的根
if booklist.hasAttribute("type") :
#判断根节点booklist是否有type属性,有则获取并打印属性的值
print(u"Root
element is", booklist.getAttribute("type"))
books =
booklist.getElementsByTagName("book") #获取booklist对象中所有book节点的list集合
print(u"book节点的个数:", books.length)
for book in books :
print("*******************book*******************")
if
book.hasAttribute("category") :
print(u"category is",
book.getAttribute("category"))
#根据节点名title拿到这个book节点下所有的title节点的集合list。
#[0]表示第一个title标签,因为一个<book>...</book>之间可能会
#定义多个title标签
title = book.getElementsByTagName(\'title\')[0]
print("Title is",
title.childNodes[0].data)
author =
book.getElementsByTagName(\'author\')[0]
print("author is",
author.childNodes[0].data)
pageNumber =
book.getElementsByTagName(\'pageNumber\')[0]
print("pageNumber is",
pageNumber.childNodes[0].data)
运行结果:
E:\>python a.py
Root element is science and engineering
book节点的个数: 2
*******************book*******************
category is math
Title is learning math
author is 张三
pageNumber is 561
*******************book*******************
category is Python
Title is learning Python
author is 李四
pageNumber is 600
9) node.haschildNodes():判断是否有子节点
判断节点node下是否有叶子节点,如果有返回True,否则返回False。但是需要注意的是,每个节点都默认有一个文本叶子节点,所以标签后面有值,就返回True,只有当标签后没值时并且也没有叶子节点时才会返回False.
import xml.dom.minidom
from xml.dom.minidom import parse
#minidom解析器打开xml文档并将其解析为内存中的一棵树
DOMTree = xml.dom.minidom.parse(r"e:\book.xml")
#获取xml文档对象,就是拿到树的根
booklist = DOMTree.documentElement
#获取booklist对象中所有book节点的list集合
books = booklist.getElementsByTagName("book")
print(u"book节点的个数:", books.length)
book节点的个数: 2
print(books[0])
<DOM Element: book at 0x21a3acd06d0>
if books[0].hasChildNodes():
print(u"存在叶子节点\n", books[0].childNodes)
else :
print(u"不存在叶子节点")
存在叶子节点
[<DOM Text node "\'\n\'">, <DOM Element: title at 0x21a3acd0768>, <DOM Text node "\'\n\'">, <DOM Element: author at 0x21a3acd0800>, <DOM Text node "\'\n\'">, <DOM Element: pageNumber at 0x21a3acd0898>, <DOM Text node "\'\n\'">]
14、xml.dom创建xml文件
创建xml文件的步骤如下:
1. 创建xml空文档(在内存中创建,未在本地生成一个文档)
2. 产生根对象
3. 往根对象里加数据
4. 把xml内存对象写到文件
1) minidom.Document():创建xml空白文档
该方法用于创建一个空白的xml文档,并返回这个doc对象
每个xml文档都是一个Document对象,代表着内存中的DOM树。
>>> import xml.dom.minidom
>>> doc = xml.dom.minidom.Document() #创建空白xml文档
>>> print(doc)
<xml.dom.minidom.Document object at 0x00000172BBBDCAC8>
2) doc.createElement(tagName):创建xml文档根节点
生成xml文档节点。参数表示要生成节点的名称
>>> import xml.dom.minidom
>>> doc = xml.dom.minidom.Document()
>>> print(doc)
<xml.dom.minidom.Document object at 0x00000172BBBDCAC8>
>>> root = doc.createElement("Manegers")
>>> print(u"添加的xml的标签为:",root.tagName)
添加的xml的标签为: Manegers #同样未写到文件中,保存在内存中。
3) node.setAttribute(attname,value):添加节点属性值对
参数说明:
attname:属性的名称
value: 属性的值
>>> root.setAttribute("company","xx科技")
>>> value = root.getAttribute("company")
>>> print("root元素的company的属性值是:",value)
root元素的company的属性值是: xx科技
4) doc.createTextNode(data):添加文本节点
>>> ceo = doc.createElement("CEO") #CEO节点并没有挂在根节点下
>>> ceo.appendChild(doc.createTextNode("吴总")) #文本节点”吴总”必须依附于element节点ceo下,等价于<CEO>吴总</CEO>
<DOM Text node "\'吴总\'">
>>> print(ceo.tagName)
CEO
5) doc/parentNode.appendChild(node):添加子节点
将节点node添加到文档对象doc作为文档树的根节点或者添加到父节点parentNode下作为其子节点。
import xml.dom.minidom
doc = xml.dom.minidom.Document() #在内存中创建一个空的文档
root = doc.createElement(\'companys\') #创建一个根节点company对象
root.setAttribute(\'name\', u\'公司信息\') # 给根节点root添加属性
doc.appendChild(root) #将根节点添加到文档对象中
company = doc.createElement(\'gloryroad\') # 给根节点添加一个叶子节点
name = doc.createElement("Name") # 叶子节点下再嵌套叶子节点
name.appendChild(doc.createTextNode(u"光荣之路教育科技公司"))#给节点添加文本节点
ceo = doc.createElement(\'CEO\')
ceo.appendChild(doc.createTextNode(u\'吴总\'))
company.appendChild(name) #将各叶子节点添加到父节点company中
company.appendChild(ceo)
root.appendChild(company) #然后将company添加到跟节点companys中
print(doc.toxml())
<?xml version="1.0" ?>
<companys name="公司信息">
<gloryroad>
<Name>光荣之路教育科技公司</Name>
<CEO>吴总</CEO>
</gloryroad>
</companys>
6) doc.writexml():生成xml文档
函数原型:
writexml(writer,indent = “”,addindent = “”,newl = “”,encoding=None)
该方法用于将内存中xml文档树写入文件中,并保存在本地磁盘
参数说明:
writer:要写的目标文件的文件对象
indent:指明根节点缩进方式
addindent:指明子节点缩进方式
newl:针对新行,指明换行方式
encoding:指明所写xml文档的编码
import xml.dom.minidom
doc = xml.dom.minidom.Document() #在内存中创建一个空的文档
root = doc.createElement(\'companys\') #创建一个根节点company对象
root.setAttribute(\'name\', u\'公司信息\') # 给根节点root添加属性
doc.appendChild(root) #将根节点添加到文档对象中
company = doc.createElement(\'gloryroad\') # 给根节点添加一个叶子节点
name = doc.createElement("Name") # 叶子节点下再嵌套叶子节点
name.appendChild(doc.createTextNode(u"光荣之路教育科技公司"))#给节点添加文本节点
ceo = doc.createElement(\'CEO\')
ceo.appendChild(doc.createTextNode(u\'吴总\'))
company.appendChild(name) #将各叶子节点添加到父节点company中
company.appendChild(ceo)
root.appendChild(company) #然后将company添加到根节点companys中
fp = open(“e:\\company.xml”,”w”,encoding = “utf-8”)
doc.writexml(fp,indent=‘ ’,addindent=”\t”,newl=”\n”,encoding =”utf-8”)
fp.close() #indent=” ”是对根节点生效的。可以看见下面的结果根节点前有个” ”
在e:\\company.xml的文件显示的内容是:
<?xml version="1.0" encoding="utf-8"?>
<companys name="公司信息">
<gloryroad>
<Name>光荣之路教育科技公司</Name>
<CEO>吴总</CEO>
</gloryroad>
</companys>
15、xml.dom创建xml的完整实例
import xml.dom.minidom
#在内存中创建一个空的文档
doc = xml.dom.minidom.Document()
#创建一个根节点Managers对象
root = doc.createElement(\'Managers\')
#设置根节点的属性
root.setAttribute(\'company\', \'xx科技\')
root.setAttribute(\'address\', \'科技软件园\')
#将根节点添加到文档对象中
doc.appendChild(root)
managerList = [{\'name\' : \'joy\', \'age\' : 27, \'sex\' : \'女\'},
{\'name\' : \'tom\', \'age\' : 30, \'sex\' : \'男\'},
{\'name\' : \'ruby\', \'age\' : 29, \'sex\' : \'女\'} ]
for i in managerList :
nodeManager = doc.createElement(\'Manager\')
nodeName = doc.createElement(\'name\')
#给叶子节点name设置一个文本节点,用于显示文本内容
nodeName.appendChild(doc.createTextNode(str(i[\'name\'])))
nodeAge = doc.createElement("age")
nodeAge.appendChild(doc.createTextNode(str(i["age"])))
nodeSex = doc.createElement("sex")
nodeSex.appendChild(doc.createTextNode(str(i["sex"])))
#将各叶子节点添加到父节点Manager中,
#最后将Manager添加到根节点Managers中
nodeManager.appendChild(nodeName)
nodeManager.appendChild(nodeAge)
nodeManager.appendChild(nodeSex)
root.appendChild(nodeManager)
#开始写xml文档
fp = open(\'e:\\Manager.xml\', \'w\')
doc.writexml(fp, indent=\'\t\', addindent=\'\t\', newl=\'\n\', encoding="utf-8")
fp.close()
Manager.xml文件的内容是:
<?xml version="1.0" encoding="utf-8"?>
<Managers address="科技软件园" company="xx科技">
<Manager>
<name>joy</name>
<age>27</age>
<sex>女</sex>
</Manager>
<Manager>
<name>tom</name>
<age>30</age>
<sex>男</sex>
</Manager>
<Manager>
<name>ruby</name>
<age>29</age>
<sex>女</sex>
</Manager>
</Managers>
16. Etree
movies.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>
1). 遍历xml文件:
import sys
try:
import xml.etree.cElementTree as ET #as ET作为别名,是用c语言写的Etree的包,比不带c的包快,但是有可能这个包没有
except ImportError:
import xml.etree.ElementTree as ET #如果没有,就引入不带c的包
tree = ET.ElementTree(file=\'e:\\movies.xml\') #打开movies.xml文件
root=tree.getroot() #获取根节点
#<Element
\'collection\' at 0x0000024FA6D96B88>
print (root.tag) #获取根节点的标签
#collection
print (root.attrib) #获取根节点的属性值,返回值是字典
#{\'shelf\': \'New Arrivals\'}
print (root.attrib[“shelf”]) #获取指定属性的属性值
#New Arrivals
for child_of_root in root:
#获取root下一级的子节点,并打印标签和属性
print (child_of_root.tag)
print ("********", child_of_root.attrib)
#movie
#******** {\'title\': \'Enemy Behind\'}
#movie
#******** {\'title\': \'Transformers\'}
#movie
#******** {\'title\': \'Trigun\'}
#movie
#********
{\'title\': \'Ishtar\'}
print ("*"*50)
# **************************************************
print (root[0].tag)
#打印一个movie
#movie
print (root[0].text) #第一个movie的文本节点,“打印的内容为一个回车”
#打印内容为一个回车
print (root[0][0].tag) #获取第一个movie下面的子节点的标签
#type
print (root[0][0].text) #获取第一个movie下面的子节点的文本内容
# War,
Thriller
print ("*"*50)
**************************************************
for elem in tree.iter():
#递归遍历所有子元素
print (elem.tag,
elem.attrib)
#collection {\'shelf\': \'New Arrivals\'}
#movie {\'title\': \'Enemy Behind\'}
#type {}
#format {}
#year {}
#rating {}
#stars {}
#description {}
#movie {\'title\': \'Transformers\'}
#type {}
#format {}
#year {}
#rating {}
#stars {}
#description {}
#movie {\'title\': \'Trigun\'}
#type {}
#format {}
#episodes {}
#rating {}
#stars {}
#description {}
#movie {\'title\': \'Ishtar\'}
#type {}
#format {}
#rating {}
#stars {}
#description {}
print ("*"*50)
**************************************************
for elem in tree.iterfind(\'movie/type\'):#查找movie下一级节点中的所有type标签
,XPATH的应用场景
print (elem.tag,
elem.attrib)
#type {}
#type {}
#type {}
#type {}
print ("*"*50)
**************************************************
for elem in tree.iter(tag=\'stars\'):#在整个树中查找标签为star的元素
print (elem.tag,
elem.attrib)
#stars {}
#stars {}
#stars {}
#stars {}
print ("*"*50)
#**************************************************
for elem in tree.iterfind(\'*[@title="Ishtar"]\'): #查找属性为title="Ishtar"的元素,iterfind是个迭代器
print (elem.tag,
elem.attrib)
#movie {\'title\': \'Ishtar\'}
print ("*"*50)
#**************************************************
for elem in tree.iterfind(\'movie[@title="Ishtar"]\'): #查找movie下属性为title="Ishtar"的元素
print (elem.tag,
elem.attrib)
#movie {\'title\': \'Ishtar\'}
print ("-"*50)
#--------------------------------------------------
root = tree.getroot()
print ("root:",root[0].tag )
#打印第一级movie元素的标签,为movie
print ("subnode:",root[0][0].tag) #打印第一级movie元素下的第一个子元素标签type
print ("subnode:",root[0][1].tag ) #打印第一级movie元素下的第二个子元素标签format
print ("subnode:",root[0][2].tag ) #打印第一级movie元素下的第三个子元素标签year
print ("subnode:",root[0][3].tag ) #打印第一级movie元素下的第四个子元素标签rating
print ("subnode:",root[0][4].tag ) #打印第一级movie元素下的第五个子元素标签stars
del root[0][4] #删除第一级movie元素下的第四个子元素
del root[0][3] #删除第一级movie元素下的第三个子元素
del root[0][2] #删除第一级movie元素下的第二个子元素
del root[0][1] #删除第一级movie元素下的第一个子元素
del root[3] #删除第四个movie元素
del root[2] #删除第三个movie元素
for subelem in root:
print (subelem.tag,
subelem.attrib) #打印四个movie元素的标签和属性
tree.write("d:\\movies.xml") #将变更的xml文件写入到文件中
2) 新建一个xml 文件:
import sys
try:
import xml.etree.cElementTree as
ET
except ImportError:
import xml.etree.ElementTree as ET
a = ET.Element(\'elem\')
#生成一个节点elem,没有文本节点
c = ET.SubElement(a,
\'child1\') #生成一个子节点下的子节点child1
c.text = "some text" #在子节点上添加文本节点
d = ET.SubElement(a,
\'child2\') #生成一个子节点下的子节点child2
b = ET.Element(\'elem_b\') #生成一个节点elem_b,没有文本节点
root = ET.Element(\'root\') #生成一个节点root
root.extend((a,
b)) #将a、b两个变量存储的节点elem和elem1添加到root节点下
tree = ET.ElementTree(root) #生成节点树
root[0].set(\'foo\', \'bar\') #设定第一个子元素的属性foo,值为bar
tree.write("d:\\test.xml")
#将xml文件内容写入到文本文件中
3) 边读边解析xml文件
#coding=utf-8
import sys
try:
import xml.etree.cElementTree as
ET
except ImportError:
import xml.etree.ElementTree as ET
tree = ET.parse("d:\\movies.xml")
count = 0
for elem in tree.iter(tag=\'movie\'): #遍历树中的movie节点
print (elem.tag)
if elem[0].text == \'War,
Thriller\':
count += 1
print (count)
#以下代码实现了边读文件边解析的作用,节省了内存
count = 0
for event, elem in ET.iterparse("d:\\movies.xml"): #遍历所有xml文件中的标签
#print (elem.tag)
if event == \'end\': #检测“闭合的”(end)事件,标签关闭
if elem.tag == \'type\' and elem.text == \'War, Thriller\': #标签为type,且文本内容为War, Thriller ,则count+1
count += 1
elem.clear() #清除元素内容,不清除则整个儿树也会在内存中,没有起到节省内存的作用。
print (count)
#事件
#start 在元素打开时触发。数据和元素的子元素仍不可用。
# end 在元素关闭时触发。所有元素的子节点,包括文本节点,现在都是可用的。
#close 在解析完成后触发。
小练习:
获取database.xml文件中的host\username\assword\databasename的值。
databases.xml:
<databaselist type="database config">
<database>
<host>localhost</host>
<username>root</username>
<password>11111</password>
<datasename>wulaoshi</datasename>
</database>
</databaselist>
程序:
from xml.dom.minidom import parse #从xml.dom.minidom模块引入解析器parse
DOMTree = parse(r"e:\databases.xml") #minidom解析器打开xml文档并将其解析为内存中的一棵树
databaselist = DOMTree.documentElement
database = databaselist.getElementsByTagName("database")
print(database)
[<DOM Element: database at 0x1e873fa6638>]
d={}
for i in range(1,8,2):
tag_name = database[0].childNodes[i].tagName
d[tag_name]=database[0].childNodes[i].childNodes[0].data
print(d)
{\'host\': \'localhost\', \'username\': \'root\', \'password\': \'11111\', \'datasename\': \'wulaoshi\'}
============================
方法1:
for k,v in d.items():
print(k,v)
host localhost
username root
password 11111
datasename wulaoshi
==============================
方法2:
host = d["host"]
username = d["username"]
password = d["password"]
datasename = d["datasename"]
print(host)
==============================