背景:在開發過程中,產生一個增刪改查保存XML文件的需求,在搜索比較好的解決方案的過程中,發現lxml庫非常好用,於是自己寫了幾個接口。
代碼如下:
# -*- coding:utf-8 -*-
from lxml import etree
class ParseXml(object):
def __init__(self, config):
parser = etree.XMLParser(remove_blank_text=True)
self.root = etree.XML(config, parser)
def addData(self, xpath, data, **kwargs):
rowData = self.root.xpath(xpath, **kwargs)
if not len(rowData) == 1:
return False
rowData[0].append(etree.Element('Param'))
last = len(rowData[0]) - 1
for k, v in data.items():
rowData[0][last].attrib[k] = v
return True
def deleteData(self, xpath, **kwargs):
rowData = self.root.xpath(xpath, **kwargs)
if not len(rowData) == 1:
return False
rowData[0].getparent().remove(rowData[0])
return True
def editData(self, xpath, data, **kwargs):
rowData = self.root.xpath(xpath, **kwargs)
if not len(rowData) == 1:
return False
for k, v in data.items():
rowData[0].attrib[k] = v
return True
def findData(self, xpath, **kwargs):
rowData = self.root.xpath(xpath, **kwargs)
return rowData
def findValue(self, xpath, key, value='value'):
rowData = self.root.xpath(xpath, name=key)
result = rowData[0].attrib.get(value, '')
return result
def saveFile(self):
return etree.tostring(self.root, encoding="utf-8", pretty_print=True)
if __name__ == '__main__':
xmlString = """
<Params>
<LocalConfig>
<Param key="ServiceIp" value="127.0.0.1" desc=""/>
<Param key="ServicePort" value="1111" desc=""/>
<Param key="DataPort" value="6655" desc=""/>
</LocalConfig>
<MysqlConfig>
<Param key="user" value="root" desc="" />
<Param key="password" value="" desc="" />
<Param key="ip" value="localhost" desc="" />
<Param key="port" value="3306" desc="" />
<Param key="db" value="testtest" desc="" />
</MysqlConfig>
</Params>
"""
testParse = ParseXml(xmlString)
string_1 = testParse.findData('//Params/LocalConfig/Param')
print('findData1', string_1)
string_2 = testParse.findData('//Param[@key=$name]', name='user')
print('findData2', string_2, string_2[0].attrib['value'])
string_3 = testParse.addData('//Params/LocalConfig', {'key': 'test', 'value': 'test', 'desc': 'test'})
print('addData', string_3)
string_4 = testParse.editData('//Params/LocalConfig/Param[@key=$name]',
{'key': 'test', 'value': 'test', 'desc': 'test1'}, name='test')
print('editData', string_4)
string_5 = testParse.deleteData('//Param[@key=$name]', name='test')
print('deleteData', string_5)
string_6 = testParse.saveFile()
print('saveData', string_6)
說明:
1,初始化的時候如果使用默認解析器,xml文件修改後會出現無換行等格式的情況,所以使用了自定義的解析器。
2,查找數據的兩個接口下面的是上面的一種特殊情況,相當於固定了特定參數。
3,在使用過程中未測試大數據量時的效率,但少數據量時效率是沒問題的。
4,初始化時傳入參數可以爲bytes和str,但爲str時不支持帶<?xml version="1.0" encoding="utf-8"?>。