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)

==============================