1. 什麼是XML?
XML 指可擴充标記語言(eXtensible Markup Language),标準通用标記語言的子集,是一種用于标記電子檔案使其具有結構性的标記語言。 XML 被設計用來傳輸和存儲資料。XML是一套定義語義标記的規則,這些标記将文檔分成許多部件并對這些部件加以辨別。它也是元标記語言,即定義了用于定義其他與特定領域有關的、語義的、結構化的标記語言的句法語言。
python對XML的解析
常見的XML程式設計接口有DOM和SAX,這兩種接口處理XML檔案的方式不同,當然使用場合也不同。
python有三種方法解析XML,SAX,DOM,以及ElementTree:
-
SAX (simple API for XML )
python 标準庫包含SAX解析器,SAX用事件驅動模型,通過在解析XML的過程中觸發一個個的事件并調用使用者定義的回調函數來處理XML檔案。
-
DOM(Document Object Model)
将XML資料在記憶體中解析成一個樹,通過對樹的操作來操作XML。
下面用到的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>
2. SAX解析xml
1). SAX是一種基于事件驅動的API。利用SAX解析XML文檔牽涉到兩個部分:解析器和事件處理器。解析器負責讀取XML文檔,并向事件處理器發送事件,如元素開始跟元素結束事件;而事件處理器則負責對事件作出相應,對傳遞的XML資料進行處理。
1、對大型檔案進行處理;
2、隻需要檔案的部分内容,或者隻需從檔案中得到特定資訊。
3、想建立自己的對象模型的時候。
2). 在python中使用sax方式處理xml要先引入xml.sax中的parse函數,還有xml.sax.handler中的ContentHandler。
ContentHandler類方法介紹
-
characters(content)方法
調用時機:
1>. 從行開始,遇到标簽之前,存在字元,content的值為這些字元串。
2>. 從一個标簽,遇到下一個标簽之前, 存在字元,content的值為這些字元串。
3>. 從一個标簽,遇到行結束符之前,存在字元,content的值為這些字元串。
4>. 标簽可以是開始标簽,也可以是結束标簽。
- startDocument()方法: 文檔啟動的時候調用。
- endDocument()方法: 解析器到達文檔結尾時調用。
- startElement(name, attrs)方法: 遇到XML開始标簽時調用,name是标簽的名字,attrs是标簽的屬性值字典。
- endElement(name)方法: 遇到XML結束标簽時調用。
3). make_parser方法
以下方法建立一個新的解析器對象并傳回。
xml.sax.make_parser( [parser_list] )
參數說明:
parser_list - 可選參數,解析器清單
4). parser方法
以下方法建立一個 SAX 解析器并解析xml文檔:
xml.sax.parse( xmlfile, contenthandler[, errorhandler])
xmlfile - xml檔案名
contenthandler - 必須是一個ContentHandler的對象
errorhandler - 如果指定該參數,errorhandler必須是一個SAX ErrorHandler對象
5). parseString方法
parseString方法建立一個XML解析器并解析xml字元串:
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
xmlstring - xml字元串
6). 示例:
import xml.sax
class MovieHandler(xml.sax.ContentHandler):
"""docstring for MovieHandler"""
def __init__(self):
super(MovieHandler, self).__init__()
self.CurrendData = ""
self.type = ""
self.format = ""
self.year = ""
self.rating = ""
self.stars = ""
self.description = ""
# 元素開始調用
def startElement(self, tag, attributes):
self.CurrendData = tag
if tag == "movie":
print("******Movie******")
title = attributes["title"]
print("Title: ", title)
pass
pass
# 元素結束調用
def endElement(self, tag):
if self.CurrendData == "type":
print("Type: ", self.type)
elif self.CurrendData == "format":
print("Format: ", self.format)
elif self.CurrendData == "year":
print("Year: ", self.year)
elif self.CurrendData == "rating":
print("Rating: ", self.rating)
elif self.CurrendData == "stars":
print("Stars: ", self.stars)
elif self.CurrendData == "description":
print("Description: ", self.description)
self.CurrendData = ""
pass
# 讀取字元時調用
def characters(self, content):
if self.CurrendData == "type":
self.type = content
elif self.CurrendData == "format":
self.format = content
elif self.CurrendData == "year":
self.year = content
elif self.CurrendData == "rating":
self.rating = content
elif self.CurrendData == "stars":
self.stars = content
elif self.CurrendData == "description":
self.description = content
pass
if (__name__ == "__main__") :
# 建立一個XMLReader
parser = xml.sax.make_parser()
# 關閉命名空間
parser.setFeature(xml.sax.handler.feature_namespaces, 0)
# 重寫 ContextHandler
handler = MovieHandler()
parser.setContentHandler(handler)
parser.parse("movies.xml")
pass
列印結果:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuczN2kzNihDOykTOjRzY5YTOhVWZzQzYwQ2NjFjNlBTMfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
圖1.png
3. Dom解析xml
檔案對象模型(Document Object Model,簡稱DOM),是W3C組織推薦的處理可擴充置智語言的标準程式設計接口。一個 DOM 的解析器在解析一個 XML 文檔時,一次性讀取整個文檔,把文檔中所有元素儲存在記憶體中的一個樹結構裡,之後你可以利用DOM 提供的不同的函數來讀取或修改文檔的内容和結構,也可以把修改過的内容寫入xml檔案。python中用xml.dom.minidom來解析xml檔案.
示例:
from xml.dom.minidom import parse
import xml.dom.minidom
# 使用minidom解析器打開XML文檔
DOMTree = xml.dom.minidom.parse("movies.xml")
# 擷取collection節點
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
print("Root element: %s" % collection.getAttribute("shelf"))
pass
# 在集合擷取所有電影
movies = collection.getElementsByTagName("movie")
# 列印每部電影的詳細資訊
for movie in movies:
print("*******Movie********")
if movie.hasAttribute("title"):
print("Title: %s" % movie.getAttribute("title"))
pass
pass
type = movie.getElementsByTagName("type")[0]
print("Type: %s" % type.childNodes[0].data)
format = movie.getElementsByTagName("format")[0]
print("Format: %s" % format.childNodes[0].data)
rating = movie.getElementsByTagName("rating")[0]
print("Rating: %s" % rating.childNodes[0].data)
description = movie.getElementsByTagName("description")[0]
print("Description: %s" % description.childNodes[0].data)
圖2.png
4. JSON解析
JSON (JavaScript Object Notation) 是一種輕量級的資料交換格式。它基于ECMAScript的一個子集。
Python3 中可以使用 json 子產品來對 JSON 資料進行編解碼,它包含了兩個函數:
- json.dumps(): 對資料進行編碼。
- json.loads(): 對資料進行解碼。
import json
# 字典
data = {
'no' : 1,
'name' : 'mazaiting',
'url' : 'https://www.jianshu.com/u/5d2cb4bfeb15'
}
# 将python字典類型裝換為JSON對象
json_str = json.dumps(data)
print("Python 原始資料: ", repr(data))
print("JSON 對象: ", json_str)
# 将JSON對象轉化為Python字典
data2 = json.loads(json_str)
print("data2['name']: ", data2['name'])
print("data2['url']: ", data2['url'])
圖3.png
5. 時間
Python 程式能用很多方式處理日期和時間,轉換日期格式是一個常見的功能。Python 提供了一個 time 和 calendar 子產品可以用于格式化日期和時間。時間間隔是以秒為機關的浮點小數。每個時間戳都以自從1970年1月1日午夜(曆元)經過了多長時間來表示。Python 的 time 子產品下有很多函數可以轉換常見日期格式。如函數time.time()用于擷取目前時間戳。
1). 擷取目前時間戳
# 引入time子產品
import time
ticks = time.time()
print("目前時間戳為:", ticks)
圖4.png
2). 時間元組
很多Python函數用一個元組裝起來的9組數字處理時間:
序号 | 字段 | 值 |
---|---|---|
4位數年 | 2008 | |
1 | 月 | 1 到 12 |
2 | 日 | 1到31 |
3 | 小時 | 0到23 |
4 | 分鐘 | 0到59 |
5 | 秒 | 0到61 (60或61 是閏秒) |
6 | 一周的第幾日 | 0到6 (0是周一) |
7 | 一年的第幾日 | 1到366 (儒略曆) |
8 | 夏令時 | -1, 0, 1, -1是決定是否為夏令時的旗幟 |
上述也就是struct_time元組。這種結構具有如下屬性:
屬性 | ||
---|---|---|
tm_year | ||
tm_mon | ||
tm_mday | 1 到 31 | |
tm_hour | 0 到 23 | |
tm_min | 0 到 59 | |
tm_sec | 0 到 61 (60或61 是閏秒) | |
tm_wday | ||
tm_yday | 一年中的第幾天,1 到 366 | |
tm_isdst | 是否為夏令時,值有:1(夏令時)、0(不是夏令時)、-1(未知),預設 -1 |
3). 擷取目前時間
從傳回浮點數的時間辍方式向時間元組轉換,隻要将浮點數傳遞給如localtime之類的函數。
import time
localtime = time.localtime(time.time())
print("本地時間為:", localtime)
圖5.png
4). 擷取格式化的時間
你可以根據需求選取各種格式,但是最簡單的擷取可讀的時間模式的函數是asctime()
import time
localtime = time.asctime(time.localtime(time.time()))
print("本地時間為:", localtime)
圖6.png
5). 格式化日期
我們可以使用 time 子產品的 strftime 方法來格式化日期:
time.strftime(format[, t])
import time
# 格式化成2016-03-20 11:45:39
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
# 格式化成Wed Apr 11 16:56:32 2018形式
print(time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()))
# 将格式字元串轉換為時間戳
a = "Wed Apr 11 16:56:32 2018"
print(time.mktime(time.strptime(a, "%a %b %d %H:%M:%S %Y")))
圖7.png
6). python中時間日期格式化符号:
%y 兩位數的年份表示(00-99)
%Y 四位數的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小時制小時數(0-23)
%I 12小時制小時數(01-12)
%M 分鐘數(00=59)
%S 秒(00-59)
%a 本地簡化星期名稱
%A 本地完整星期名稱
%b 本地簡化的月份名稱
%B 本地完整的月份名稱
%c 本地相應的日期表示和時間表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等價符
%U 一年中的星期數(00-53)星期天為星期的開始
%w 星期(0-6),星期天為星期的開始
%W 一年中的星期數(00-53)星期一為星期的開始
%x 本地相應的日期表示
%X 本地相應的時間表示
%Z 目前時區的名稱
%% %号本身
7). 日期
Calendar子產品有很廣泛的方法用來處理年曆和月曆.
# 擷取某月月曆
import calendar
cal = calendar.month(2018, 4)
print("以下輸出2016年1月份的月曆:")
print(cal)
圖8.png