背景:在开发过程中,产生一个增删改查保存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 = """
"""
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时不支持带。