程式碼託管位置 github-pytools
需求
在實際應用中,需要對xml配置檔案進行實時修改,
1.增加、刪除 某些節點
2.增加,刪除,修改某個節點下的某些屬性
3.增加,刪除,修改某些節點的文字
使用xml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
name="AProcesser" file="lib64/A.so" path="/tmp"> name="BProcesser" file="lib64/B.so" value="fordelete"> name="BProcesser" file="lib64/B.so2222222"/> name="search" prefix="/bin/search?" output_formatter="OutPutFormatter:service_inc"> sequency="chain1"/> sequency="chain2"> name="update" prefix="/bin/update?"> sequency="chain3" value="fordelete"/> |
實現思想
使用ElementTree,先將檔案讀入,解析成樹,之後,根據路徑,可以定位到樹的每個節點,再對節點進行修改,最後直接將其輸出
實現程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
#!/usr/bin/python # -*- coding=utf-8 -*- # author : wklken@yeah.net # 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") |
修改後的結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
file="lib64/A.so" name="AProcesser" path="/tmp"> age="1" file="lib64/B.so" name="BProcesser"> age="15" money="200000">this is the firest content age="1" file="lib64/B.so2222222" name="BProcesser"> age="15" money="200000">this is the firest content name="search" output_formatter="OutPutFormatter:service_inc" prefix="/bin/search?"> sequency="chain2" /> name="update" prefix="/bin/update?"> sequency="chain3" value="fordelete">new text |
The end!
打賞支援我寫出更多好文章,謝謝!
打賞作者
打賞支援我寫出更多好文章,謝謝!
任選一種支付方式