python3 readWriteXml_xml.etree.py

"""
模塊:python3 readWriteXml_xml.etree.py
功能:python3 讀寫 xml。
知識點:
xml.etree 知識點.txt
"""
from xml.etree.ElementTree import ElementTree, Element


def readXml(xmlPath):
    """
    讀取並解析 xml 文件。
    :param xmlPath: xml 文件路徑。
    :return: xmlTree,xml 節點樹,起始就是“根元素”。
    """
    xmlTree = ElementTree()
    xmlTree.parse(xmlPath)
    return xmlTree


def writeXml(xmlTree, filePath):
    """
    將 xmlTree 寫到文件。
    :param xmlTree: xml 節點樹,起始就是“根元素”。
    :param filePath: 文件路徑。
    :return:
    """
    xmlTree.write(filePath, encoding="utf-8", xml_declaration=True)


def if_match(nodeToCheck, kv_map):
    """
    判斷某個節點,是否匹配所有傳入鍵值對。
    :param nodeToCheck: 待查節點。
    :param kv_map: 屬性值對的字典。
    :return: True/False
    """
    for key in kv_map:
        if nodeToCheck.get(key) != kv_map.get(key):
            return False
    return True


def getNodesByPath(xmlTree, path):
    """
    查找某個路徑匹配的所有節點。
    :param xmlTree: xml 節點樹,起始就是“根元素”。
    :param path: 節點路徑,如:"./book"。
    :return: [ele1,ele2,...]
    """
    return xmlTree.findall(path)


def getNodesByKVMap(nodesToMatch, kv_map):
    """
    根據屬性及屬性值查找符合的節點。
    :param nodesToMatch: 待匹配的節點列表。
    :param kv_map: 匹配屬性及其值的字典。
    :return: 匹配節點的列表。
    """
    result_nodes = []
    for node in nodesToMatch:
        if if_match(node, kv_map):
            result_nodes.append(node)
    return result_nodes


def update_deleteOfNodesProperties(nodelist, kv_map, delete=False):
    """
    增加、修改(默認)/刪除 節點的屬性及其值。
    :param nodelist: 節點列表
    :param kv_map: 屬性值的字典。
    :param delete: 刪除節點的 kv_map 中的屬性嗎?
    :return: None.
    """
    for node in nodelist:
        for key in kv_map:
            if delete:
                if key in node.attrib:
                    del node.attrib[key]
            else:
                node.set(key, kv_map.get(key))


def setAppendDeleteNodesText(nodelist, newText, append=False, delete=False):
    """
    賦值(默認)/追加/刪除一些節點的文本。
    :param nodelist: 節點列表
    :param newText: 新文本
    :param append:  追加文本?
    :param delete: 刪除文本?
    :return: None.
    """
    for node in nodelist:
        if append:
            node.text += newText
        elif delete:
            node.text = ""
        else:
            node.text = newText


def create_node(tag, kv_map, innerText):
    """
    創建節點。
    :param tag: 節點標籤
    :param kv_map: 屬性值字典。
    :param innerText: 節點閉合標籤裏的文本.
    :return: 新節點
    """
    element = Element(tag, kv_map)
    element.text = innerText
    return element


def add_child_node(nodelist, element):
    """
    給一些節點添加子節點。
    :param nodelist: 節點列表
    :param element: 子節點
    :return:
    """
    for node in nodelist:
        node.append(element)


def delNodesByTagKV_map(parentNodes, tagToDel, tagAttrib):
    """
    通過標籤及屬性值定位一個節點,並刪除之。
    :param parentNodes: 父節點列表
    :param tagToDel: 子節點標籤
    :param tagAttrib: 屬性及其值的字典。
    :return:
    """
    for parent_node in parentNodes:
        children = parent_node.getchildren()
        for child in children:
            if child.tag == tagToDel and if_match(child, tagAttrib):
                parent_node.remove(child)


if __name__ == "__main__":
    # 1. 讀取xml文件
    xmlTree = readXml("bookList.xml")
    print("1.xmlTree:", xmlTree)

    # 2. 屬性修改
    # A. 找到父節點
    nodes = getNodesByPath(xmlTree, "./book")
    print("2.1.nodes:", nodes)
    # B. 通過屬性準確定位子節點
    result_nodes = getNodesByKVMap(nodes, {"category": "math"})
    print("2.2.result_nodes:", result_nodes)
    # C. 修改節點屬性
    update_deleteOfNodesProperties(result_nodes, {"age": "1"})
    print("2.3.", result_nodes[0].attrib)
    # 2.3. {'category': 'math', 'age': '1'}
    # D. 刪除節點屬性
    update_deleteOfNodesProperties(result_nodes, {"age": ""}, True)
    print("2.4.", result_nodes[0].attrib)
    # 2.4. {'category': 'math'}

    # 3. 添加節點
    # A.新建節點
    newNode = create_node("person", {"age": "15", "money": "20000"}, "this is innerText")
    # B.插入到父節點之下
    add_child_node(result_nodes, newNode)
    print("3.", result_nodes[0].getchildren())

    # 4. 刪除節點
    # 定位父節點
    parent_nodes = getNodesByPath(xmlTree, "book")
    # 準確定位子節點並刪除之
    delNodesByTagKV_map(parent_nodes, "author", {"id": "zhang"})
    print("4.", parent_nodes[0].getchildren())

    # 5. 修改節點文本
    # 定位節點
    text_nodes = getNodesByKVMap(getNodesByPath(xmlTree, "book/pageNumber"), {"id": "p1"})
    setAppendDeleteNodesText(text_nodes, "666")

    # 6. 輸出到結果文件
    writeXml(xmlTree, "bookList2.xml")

 

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