""" 模塊: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")