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)
==============================
python进阶(十七)xml(下)的更多相关文章
- python进阶(四) windows下虚拟环境使用
虚拟环境作用: 1. 通常开发一个项目,会安装很多的第三方包,这时第三方包我们是安装在本机环境的.那么如果项目进行部署或移植的时候是不是要重新安装这些包???? 2.开发环境,同时在做两相项目,同时要 ...
- Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究
Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: 反射的概念是由Smith在1982年首次提出的 ...
- Python进阶之模块
在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很 ...
- 用 ElementTree 在 Python 中解析 XML
用 ElementTree 在 Python 中解析 XML 原文: http://eli.thegreenplace.net/2012/03/15/processing-xml-in-python- ...
- python标准库xml.etree.ElementTree的bug
使用python生成或者解析xml的方法用的最多的可能就数python标准库xml.etree.ElementTree和lxml了,在某些环境下使用xml.etree.ElementTree更方便一些 ...
- Python进阶 - 对象,名字以及绑定
Python进阶 - 对象,名字以及绑定 1.一切皆对象 Python哲学: Python中一切皆对象 1.1 数据模型-对象,值以及类型 对象是Python对数据的抽象.Python程序中所有的数据 ...
- [python标准库]XML模块
1.什么是XML XML是可扩展标记语言(Extensible Markup Language)的缩写,其中的 标记(markup)是关键部分.您可以创建内容,然后使用限定标记标记它,从而使每个单词. ...
- Python进阶-继承中的MRO与super
Python进阶-继承中的MRO与super 写在前面 如非特别说明,下文均基于Python3 摘要 本文讲述Python继承关系中如何通过super()调用"父类"方法,supe ...
- Python进阶 - 命名空间与作用域
Python进阶 - 命名空间与作用域 写在前面 如非特别说明,下文均基于Python3 命名空间与作用于跟名字的绑定相关性很大,可以结合另一篇介绍Python名字.对象及其绑定的文章. 1. 命名空 ...
- python专题-读取xml文件
关于python读取xml文章很多,但大多文章都是贴一个xml文件,然后再贴个处理文件的代码.这样并不利于初学者的学习,希望这篇文章可以更通俗易懂的教如何使用python 来读取xml 文件. 什么是 ...
随机推荐
- python Threading模块源码解析
查看源码: 这是一个线程控制的类,这个类可以被子类化(继承)在一定的条件限制下,这里有两种方式去明确活动:第一通过传入一个callable 对象也就是调用对象,一种是通过重写这个Thread类的run ...
- Web 开发人员推荐的通用独立 UI 组件
现代 Web 开发在将体验和功能做到极致的同时,对于美观的追求也越来越高.在推荐完图形库之后,再来推荐一些精品的独立 UI 组件.这些组件可组合在一起,形成美观而交互强大的 Web UI . 给 We ...
- HTML的表单初级验证
HTML的表单初级验证 placeholder(提示信息) required(确保不能为空) pattern(正则表达式验证) 1. placeholder(提示信息) 语法: <p>账号 ...
- LaTeX 文字带边框
1.使用framed宏包 \usepackage{framed} 可以使用verb|...|和verbatim环境而不使用cprotect宏包的cprotect命令 \begin{framed} \v ...
- NVMe概况
简介 NVMe是为满足企业和客户系统需求,利用基于PCIe的固态存储,而精心设计的一个优化的,高效的,可伸缩主机控制器接口.NVMe是为非易失性内存(NVM)技术从头开始全新构建的,目的在于超越硬盘驱 ...
- PolandBall and Forest
PolandBall lives in a forest with his family. There are some trees in the forest. Trees are undirect ...
- linux 部署 .net 程序
1.使用jexus https://www.jexus.org/ 2.“loopback”错误
- 线程同步器CountDownLatch
Java程序有的时候在主线程中会创建多个线程去执行任务,然后在主线程执行完毕之前,把所有线程的任务进行汇总,以前可以用线程的join方法,但是这个方法不够灵活,我们可以使用CountDownLatch ...
- AcWing 125. 耍杂技的牛
//按照wi+si从小到大的顺序排,结果一定最优,最大的危险系数一定是最小的 //类比于国王游戏 #include <iostream> #include <algorithm> ...
- Apache Kafka(四)- 使用 Java 访问 Kafka
1. Produer 1.1. 基本 Producer 首先使用 maven 构建相关依赖,这里我们服务器kafka 版本为 2.12-2.3.0,pom.xml 文件为: <?xml vers ...