Python xml屬性/節點/文本的增刪改[xml.etree.ElementTree]

需求:

在實際應用中,需要對xml配置文件進行實時修改, 

 1.增加、刪除 某些節點

 2.增加,刪除,修改某個節點下的某些屬性

 3.增加,刪除,修改某些節點的文本


xml源文件格式[例]

<?xml version="1.0" encoding="UTF-8"?>  
<framework>  
    <processers>  
        <processer name="AProcesser" file="lib64/A.so"  
            path="/tmp">  
        </processer>  
        <processer name="BProcesser" file="lib64/B.so" value="fordelete">  
        </processer>  
        <processer name="BProcesser" file="lib64/B.so2222222"/>  
          
        <services>  
            <service name="search" prefix="/bin/search?"  
                output_formatter="OutPutFormatter:service_inc">  
                  
                <chain sequency="chain1"/>  
                <chain sequency="chain2"></chain>  
            </service>  
            <service name="update" prefix="/bin/update?">  
                <chain sequency="chain3" value="fordelete"/>  
            </service>  
        </services>  
    </processers>  
</framework> 

使用庫:

xml.etree.ElementTree 

官方文檔地址:http://docs.python.org/library/xml.etree.elementtree.html


實現思想:

使用ElementTree,先將文件讀入,解析成樹,之後,根據路徑,可以定位到樹的每個節點,再對節點進行修改,最後直接將其輸出


代碼附文檔:

#!/usr/bin/python  
# -*- coding=utf-8 -*-  
# author : [email protected]  
# date: 2012-05-25  
# version: 0.1  
  
from xml.etree.ElementTree import ElementTree,Element  
  
def read_xml(in_path):  
    '''''讀取並解析xml文件 
       in_path: xml路徑 
       return: ElementTree'''  
    tree = ElementTree()  
    tree.parse(in_path)  
    return tree  
  
def write_xml(tree, out_path):  
    '''''將xml文件寫出 
       tree: xml樹 
       out_path: 寫出路徑'''  
    tree.write(out_path, encoding="utf-8",xml_declaration=True)  
  
def if_match(node, kv_map):  
    '''''判斷某個節點是否包含所有傳入參數屬性 
       node: 節點 
       kv_map: 屬性及屬性值組成的map'''  
    for key in kv_map:  
        if node.get(key) != kv_map.get(key):  
            return False  
    return True  
  
#---------------search -----  
  
def find_nodes(tree, path):  
    '''''查找某個路徑匹配的所有節點 
       tree: xml樹 
       path: 節點路徑'''  
    return tree.findall(path)  
  
  
def get_node_by_keyvalue(nodelist, kv_map):  
    '''''根據屬性及屬性值定位符合的節點,返回節點 
       nodelist: 節點列表 
       kv_map: 匹配屬性及屬性值map'''  
    result_nodes = []  
    for node in nodelist:  
        if if_match(node, kv_map):  
            result_nodes.append(node)  
    return result_nodes  
  
#---------------change -----  
  
def change_node_properties(nodelist, kv_map, is_delete=False):  
    '''''修改/增加 /刪除 節點的屬性及屬性值 
       nodelist: 節點列表 
       kv_map:屬性及屬性值map'''  
    for node in nodelist:  
        for key in kv_map:  
            if is_delete:   
                if key in node.attrib:  
                    del node.attrib[key]  
            else:  
                node.set(key, kv_map.get(key))  
              
def change_node_text(nodelist, text, is_add=False, is_delete=False):  
    '''''改變/增加/刪除一個節點的文本 
       nodelist:節點列表 
       text : 更新後的文本'''  
    for node in nodelist:  
        if is_add:  
            node.text += text  
        elif is_delete:  
            node.text = ""  
        else:  
            node.text = text  
              
def create_node(tag, property_map, content):  
    '''''新造一個節點 
       tag:節點標籤 
       property_map:屬性及屬性值map 
       content: 節點閉合標籤裏的文本內容 
       return 新節點'''  
    element = Element(tag, property_map)  
    element.text = content  
    return element  
          
def add_child_node(nodelist, element):  
    '''''給一個節點添加子節點 
       nodelist: 節點列表 
       element: 子節點'''  
    for node in nodelist:  
        node.append(element)  
          
def del_node_by_tagkeyvalue(nodelist, tag, kv_map):  
    '''''同過屬性及屬性值定位一個節點,並刪除之 
       nodelist: 父節點列表 
       tag:子節點標籤 
       kv_map: 屬性及屬性值列表'''  
    for parent_node in nodelist:  
        children = parent_node.getchildren()  
        for child in children:  
            if child.tag == tag and if_match(child, kv_map):  
                parent_node.remove(child)  
                          
  
  
if __name__ == "__main__":  
      
    #1. 讀取xml文件  
    tree = read_xml("./test.xml")  
      
    #2. 屬性修改  
      #A. 找到父節點  
    nodes = find_nodes(tree, "processers/processer")  
      #B. 通過屬性準確定位子節點  
    result_nodes = get_node_by_keyvalue(nodes, {"name":"BProcesser"})  
      #C. 修改節點屬性  
    change_node_properties(result_nodes, {"age": "1"})  
      #D. 刪除節點屬性  
    change_node_properties(result_nodes, {"value":""}, True)  
      
    #3. 節點修改  
      #A.新建節點  
    a = create_node("person", {"age":"15","money":"200000"}, "this is the firest content")  
      #B.插入到父節點之下  
    add_child_node(result_nodes, a)  
      
    #4. 刪除節點  
       #定位父節點  
    del_parent_nodes = find_nodes(tree, "processers/services/service")  
       #準確定位子節點並刪除之  
    target_del_node = del_node_by_tagkeyvalue(del_parent_nodes, "chain", {"sequency" : "chain1"})  
      
    #5. 修改節點文本  
       #定位節點  
    text_nodes = get_node_by_keyvalue(find_nodes(tree, "processers/services/service/chain"), {"sequency":"chain3"})  
    change_node_text(text_nodes, "new text")  
      
    #6. 輸出到結果文件  
    write_xml(tree, "./out.xml")  


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