1. 程式人生 > >三十二、python操作XML檔案

三十二、python操作XML檔案

'''
XML:模組

xml總結

1、解析
str
檔案
tree,ElementTree,type

root,Element,type
2、操作
Element:
tag,text,find,iter,get,set...

3、重新寫入
tree.write()
str沒有tree--->ElementTree(root)
tree.write(xx,encoding='utf-8',xxx,xxx)

4、建立xml
Element(xx,xx)
5、縮排
6、名稱空間

xx.find(xxx):獲取第一個尋找到的子節點
xx.findtext(xxx):獲取到第一個找到的子節點的內容
xx.findall(aaa):獲取所有的aaa節點
xx.tag:標籤名
xx.text:子節點的內容
xx.attrib:子節點的屬性
xx.makeelement(xxx):建立一個新的節點,僅為建立
ET.ElementTree(xxx.xml):生成文件物件
xx.append(son):為當前節點添加個子節點
xx.iter(aaa):獲取指定節點,併為之建立一個迭代器for迴圈
xx.iterfind(aaa):獲取指定節點,併為之建立一個迭代器for迴圈
xx.get(aa):獲取當前節點xx中屬性aa(key)的值
xx.set(key,value):設定當前節點的屬性值,最後再write寫入檔案
xx.keys():獲取當前節點所有屬性的keys,返回列表
xx.items():獲取當前節點的所有屬性值,每對屬性都是鍵值對
xx.itertext():獲取當前節點中子孫節點的所有內容,並返回一個迭代器,for
'''
1.檢測qq是否線上
from xml.etree import ElementTree as ET
import requests
response=requests.get('http://www.webxml.com.cn/webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=55465165')
response.encoding="utf-8"
result=response.text
print(result)
e=ET.XML(result)
print (e.text)
if e.text=="Y":
    print("線上")
else:
    print("離線")
------------------------------------------------------------------

   <?xml version="1.0" encoding="utf-8"?>
   <string xmlns="http://WebXml.com.cn/">Y</string>
   Y
   線上

------------------------------------------------------------------
2.列車時刻表
#讀取xml中的內容
import requests
from xml.etree import ElementTree as ET
response=requests.get('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=K234&UserID=')
response.encoding="utf-8"
result=response.text
print(result)
e=ET.XML(result)
print (e.text)
for i in e.iter("TrainDetailInfo"):
    print(i.find("TrainStation").text,i.find("ArriveTime").text,i.tag,i.attrib)
-----------------------------------------------------------------------------

   上海(車次:K234\K235) None TrainDetailInfo {'{urn:schemas-microsoft-com:xml-diffgram-v1}id': 'TrainDetailInfo1', '{urn:schemas-microsoft-com:xml-msdata}rowOrder': '0', '{urn:schemas-microsoft-com:xml-diffgram-v1}hasChanges': 'inserted'}
   崑山 11:44:00 TrainDetailInfo {'{urn:schemas-microsoft-com:xml-diffgram-v1}id': 'TrainDetailInfo2', '{urn:schemas-microsoft-com:xml-msdata}rowOrder': '1', '{urn:schemas-microsoft-com:xml-diffgram-v1}hasChanges': 'inserted'}
   蘇州 12:12:00 TrainDetailInfo {'{urn:schemas-microsoft-com:xml-diffgram-v1}id': 'TrainDetailInfo3', '{urn:schemas-microsoft-com:xml-msdata}rowOrder': '2', 

-----------------------------------------------------------------------------
3.
#開啟本地的xml檔案,並讀取內容(只能讀取,不能修改)
############ 解析方式一 ############
res_xml=ET.XML(open("first.xml","r",encoding="utf-8").read())
print(res_xml)
for i in res_xml.iter('country'):
    print (i.tag,i.attrib,i.find("rank").text,i.find("gdppc").text)
---------------------------------------------------------------------------

   <Element 'data' at 0x0000017EE58003B8>
   country {'name': 'Liechtenstein'} 2 141100
   country {'name': 'Singapore'} 5 59900
   country {'name': 'Panama'} 69 13600

---------------------------------------------------------------------------
############ 解析方式二 ############
#並修改其中的內容
# 直接解析xml檔案
tree=ET.parse("first.xml")
print (tree)
# 獲取xml檔案的根節點
root=tree.getroot()
print(root)

for i in root.iter("year"):
    print(i.tag,i.attrib,i.text)
    #讓year的值自增1
    new_year=int(i.text)+1
    print(new_year)
    #自增1後賦值給i.text
    i.text=str(new_year)
    #更改或增加year的屬性值
    i.set('name','nian')
    i.set('age', '18')
    #刪除屬性值
    del i.attrib['name']

tree.write("first.xml")
---------------------------------------------------------------------------

   <xml.etree.ElementTree.ElementTree object at 0x0000017EE6180668>
   <Element 'data' at 0x0000017EE615F6D8>
   year {'age': '18'} 2033
   2034
   year {'age': '18'} 2036
   2037
   year {'age': '18'} 2036
   2037

---------------------------------------------------------------------------
4.getroot中的方法
'''
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'attrib', 'clear', 'extend', 'find', 'findall', 'findtext', 'get', 'getchildren', 'getiterator', 'insert', 'items', 'iter', 'iterfind', 'itertext', 'keys', 'makeelement', 'remove', 'set', 'tag', 'tail', 'text']
tag
attrib
find
set
iter
set
get
'''
tree=ET.parse("first.xml")
root=tree.getroot()
print(dir(root))


'''
5.建立xml文件
'''
5.1建立方式一:
from xml.etree import ElementTree as ET


# 建立根節點
root = ET.Element("famliy")


# 建立子節點
son1 = ET.Element('son', {'name': 'a1'})
# 建立小兒子
son2 = ET.Element('son', {"name": 'a2'})

# 在子節點中建立子節點
grandson1 = ET.Element('grandson', {'name': 'a11'})
grandson2 = ET.Element('grandson', {'name': 'a12'})
#將位元組點中的子節點追加到子節點中
son1.append(grandson1)
son1.append(grandson2)


# 將子節點追加到根節點中
root.append(son1)
root.append(son1)
#儲存
tree = ET.ElementTree(root)
tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False) 
#enccoding=utf-8儲存內容中有中文時
short_empty_elements=False:不會自動加自閉(<vv a2="888"></vv>)
xml_declaration=True:自動會在xml的頂部加上“<?xml version='1.0' encoding='utf-8'?>
5.2建立方式二
from xml.etree import ElementTree as ET

# 建立根節點
root = ET.Element("famliy")


# 建立子節點1
# son1 = ET.Element('son', {'name': 'a1'})
son1 = root.makeelement('son', {'name': 'a1'})
# 建立子節點2
# son2 = ET.Element('son', {"name": 'a2'})
son2 = root.makeelement('son', {"name": 'a2'})

# 在子節點中建立子節點
# grandson1 = ET.Element('grandson', {'name': 'a11'})
grandson1 = son1.makeelement('grandson', {'name': 'a11'})
# grandson2 = ET.Element('grandson', {'name': 'a12'})
grandson2 = son1.makeelement('grandson', {'name': 'a12'})
#將子節點中的子節點追加到子節點中
son1.append(grandson1)
son1.append(grandson2)


# 把子節點追加到根節點中
root.append(son1)
root.append(son1)
#儲存
tree = ET.ElementTree(root)
tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)
5.3建立方式三
#建立根節點
new_xml=ET.Element("namelist")

#建立根節點下的子節點1
name1=ET.SubElement(new_xml,"name",attrib={'a1':'aa1'})
#子節點下的子節點
age1=ET.SubElement(name1,"age",attrib={'a2':'aa2'})
sex1=ET.SubElement(name1,"sex")
sex1.text='66'

#建立子節點2
name2=ET.SubElement(new_xml,"name",attrib={'aa1':'aaa1'})
#建立子節點下的子節點
age2=ET.SubElement(name1,"age",attrib={'aa2':'aaa2'})
sex2=ET.SubElement(name1,"sex")
sex2.text='88'

new_year=ET.SubElement(name2,"year")
new_year.text='2018'
#儲存
et = ET.ElementTree(new_xml)  #生成文件物件
et.write("test.xml", encoding="utf-8", xml_declaration=True, short_empty_elements=False)
'''
6.xml補充:
'''
6.1使用makeelement建立一個節點
  append()追加至某個節點
from xml.etree import ElementTree as ET

#開啟xml檔案
tree=ET.parse("first.xml")
#獲取根節點
root=tree.getroot()
print(root,root.tag,root.attrib,root.text)

#建立節點makeelement,建立一個element物件
son=root.makeelement("kk",{'a1':'222'})
print(son)
son.text="666"
sub_son=son.makeelement("vv",{'a2':'888'})
#為當前節點追加一個子節點
root.append(son)
son.append(sub_son)
#寫入檔案
#tree.write("first.xml",short_empty_elements=False)
print("---------------------------------------------------------------------------------------")

'''
6.2其他建立節點方式,ET.Element()
'''
ele1=ET.Element("p1",{'a3':'333'})
ele2=ET.Element("p2",{'a4':'444'})
son.append(ele1)
ele1.append(ele2)

#tree.write("first.xml")

print("---------------------------------------------------------------------------------------")


'''
6.3 tree:
物件都是有類建立,物件所有的功能都與其相關的類中
1.ElementTree類建立,ElementTree(xxx)
2.getroot()獲取xml的根節點
3.write()記憶體中xml寫入檔案中
'''
from xml.etree.ElementTree import ElementTree
from xml.etree.ElementTree import Element
tree=ET.parse("first.xml")
print(tree,type(tree))
root=tree.getroot()
print(root,type(root))

print("---------------------------------------------------------------------------------------")
7.兩種修改xml檔案方式
  A、字串形式開啟
from xml.etree import ElementTree as ET

############ 解析字串方式開啟 ############

# 開啟檔案,讀取XML內容
new_xml = open('first.xml', 'r').read()

# 將字串解析成xml特殊物件,root代指xml檔案的根節點
root = ET.XML(new_xml)

############ 操作 ############

# 頂層標籤
print(root.tag)

# 遍歷data下的所有country節點
for i in root.findall('country'):
    # 獲取每一個i節點下rank節點的內容
    rank = int(i.find('rank').text)

    if rank > 50:
        # 刪除指定country節點
        root.remove(i)

############ 儲存檔案 ############
tree = ET.ElementTree(root)
tree.write("newnew.xml", encoding='utf-8')
  B、以解析檔案開啟
from xml.etree import ElementTree as ET

############ 解析檔案方式 ############

# 直接解析xml檔案
tree = ET.parse("first.xml")

# 獲取xml檔案的根節點
root = tree.getroot()

############ 操作 ############

# 頂層標籤
print(root.tag)

# 遍歷data下的所有country節點
for i in root.findall('country'):
    # 獲取每一個i節點下rank節點的內容
    rank = int(i.find('rank').text)

    if rank > 50:
        # 刪除指定country節點
        root.remove(i)

############ 儲存檔案 ############
tree.write("first.xml", encoding='utf-8')
8.儲存xml右縮排
'''
from xml.dom import minidom:由於原生儲存的XML時預設無縮排,如果想要設定縮排的話, 需要修改儲存方式:
'''


from xml.etree import ElementTree as ET
from xml.dom import minidom


def func(elem):
    '''
    將節點轉化成字串,並新增縮排
    :param elem:
    :return:
    '''
    rough_string=ET.tostring(elem,'utf-8')
    reparsed=minidom.parseString(rough_string)
    #返回縮排
    return reparsed.toprettyxml(indent="\t")

# 建立根節點
root = ET.Element("famliy")


# 建立子節點
son1 = ET.Element('son', {'name': 'a1'})
# 建立小兒子
son2 = ET.Element('son', {"name": 'a2'})

# 在子節點中建立子節點
grandson1 = ET.Element('grandson', {'name': 'a11'})
grandson2 = ET.Element('grandson', {'name': 'a12'})
#將位元組點中的子節點追加到子節點中
son1.append(grandson1)
son1.append(grandson2)


# 將子節點追加到根節點中
root.append(son1)
root.append(son1)
#儲存
r=func(root)
f=open('oooo.xml','w',encoding='utf-8')
f.write(r)
f.close()