Python學習筆記之XML讀、寫

在有些項目中,有時候會用到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修改,完全可以滿足,前後對比文件如下所示:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章