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)
==============================
?
轉載于:https://www.cnblogs.com/suitcases/p/11043575.html
總結
以上是生活随笔為你收集整理的python进阶(十七)xml(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用AJAX Toolkit创建新闻列表
- 下一篇: SharePoint GridView的