在有些項目中,有時候會用到XML的讀寫功能,用C、C++去編輯不太方便,但是使用Python去做就很方便了。這邊僅是初次編寫,給個簡單示例,做拋磚引玉之用,歡迎大家在此基礎進行擴展、並使用。
1.庫引用
from xml.etree.ElementTree import *
2.功能集成代碼
如下部分代碼,僅僅是對我用到了的Element部分功能做了初步的封裝,這樣在後續使用起來更爲方便,也可以做進一步的擴展。
newItem是新建一個element,併爲其賦值,這個在Python的官方文檔裏介紹的比較詳細,可以參考,另外在使用其作爲測試例子時,同時可以使用dump接口打印出自己的編輯的xml文件;
addchild則是把element加入到tree中,Python比較簡單,C++中也有類似的接口;
setItemAttrib這個可以對element的屬性進行刪除,修改;
class ZElement:
def newItem(self, tag, text=None):
element = Element(tag)
element.text = text
return element
def addChild(self, item, subItem):
item.append(subItem)
def setItemAttrib(self, items, kvMap, isDel=False):
for item in items:
for key in kvMap:
if isDel:
if key in item.attrib:
del item.attrib[key]
else:
items.set(key, kvMap.get(key))
進一步的集成code如下所示:
class ZXML(ZElement):
def __init__(self):
self._root = ElementTree()
def setRoot(self, items):
self._root = ElementTree(items)
def _indent(self, items, level=0):
i = "\n" + level * "\t"
if len(items):
if not items.text or not items.text.strip():
items.text = i + "\t"
if not items.tail or not items.tail.strip():
items.tail = i
for item in items:
self._indent(item, level + 1)
if not items.tail or not items.tail.strip():
items.tail = i
else:
if level and (not items.tail or not items.tail.strip()):
items.tail = i
def parse(self, path):
self._root.parse(path)
return self._root
def save(self, path):
self._root.write(path, encoding="utf-8", xml_declaration=True,
short_empty_elements=False)
def format(self, items):
self._indent(items)
def setItemText(self, item, text):
if type(item) == str:
items = self._root.findall(item)
for it in items:
it.text = text
else:
item.text = text
def findItems(self, itemPath):
if self._root is not None:
return self._root.findall(itemPath)
def deleteItems(self, itemPath, subTag):
items = self.findItems(itemPath)
for item in items:
for child in list(item):
if child.tag == subTag:
item.remove(child)
return items
上述代碼比較簡單,滿足增、刪、改沒有問題的;_intent這個是對xml進行縮進操作;其它接口極爲簡單,我就不做說明。
下面就一個例子進行說明(如下是一個示例XML文件,保存爲test.proj):
<?xml version='1.0' encoding='utf-8'?>
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_proj.xsd">
<SchemaVersion>1.1</SchemaVersion>
<Targets>
<Target>
<TargetOption>
<TargetArmAds>
<LDads>
<Misc>--keep</Misc>
</LDads>
</TargetArmAds>
</TargetOption>
<Groups></Groups>
</Target>
</Targets>
</Project>
對XML文件自動化修改後,如下所是:
<?xml version='1.0' encoding='utf-8'?>
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_proj.xsd">
<SchemaVersion>1.1</SchemaVersion>
<Targets>
<Target>
<TargetOption>
<TargetArmAds>
<LDads>
<Misc>--keep PatchM_VCODEC_Adapter_DacDataIn4TEST</Misc>
</LDads>
</TargetArmAds>
</TargetOption>
<Groups>
<Group>
<GroupName>PATCH_Add_Linein_HIFAlgo_by_WDX_LCY1</GroupName>
<Files>
<File>
<FileName>PatchM_VCODEC_Adapter_DacDataIn4TEST.c</FileName>
<FileType>1</FileType>
<FilePath>.\app\PATCH_Add_Linein_HIFAlgo_by_WDX_LCY\PatchM_VCODEC_Adapter_DacDataIn4TEST.c</FilePath>
</File>
</Files>
</Group>
</Groups>
</Target>
</Targets>
</Project>
那是如何實現上述功能的呢,請查看如下如下Code:
if __name__ == "__main__":
zxml = ZXML()
zxml.parse(r'./src/test.proj')
items = zxml.deleteItems("Targets/Target/Groups", 'Group')
FileName = zxml.newItem("FileName", "PatchM_VCODEC_Adapter_DacDataIn4TEST.c")
FileType = zxml.newItem("FileType", "1")
FilePath = zxml.newItem("FilePath",
r".\app\PATCH_Add_Linein_HIFAlgo_by_WDX_LCY\PatchM_VCODEC_Adapter_DacDataIn4TEST.c")
file = zxml.newItem("File")
zxml.addChild(file, FileName)
zxml.addChild(file, FileType)
zxml.addChild(file, FilePath)
files = zxml.newItem("Files")
zxml.addChild(files, file)
GroupName = zxml.newItem("GroupName", "PATCH_Add_Linein_HIFAlgo_by_WDX_LCY1")
Group = zxml.newItem("Group")
zxml.addChild(Group, GroupName)
zxml.addChild(Group, files)
zxml.addChild(items[0], Group)
zxml.format(items[0])
zxml.setItemText('Targets/Target/TargetOption/TargetArmAds/LDads/Misc', '--keep PatchM_VCODEC_Adapter_DacDataIn4TEST')
zxml.save("./src/out.proj")
最終完成也是非常的簡單,對簡單的XML修改,完全可以滿足,前後對比文件如下所示: