1. 程式人生 > >python 處理xml文件

python 處理xml文件

bsp article chan 參數 object cif 應用 -s 列表

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

1.增加、刪除 某些節點

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

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

<annotation>
  <folder>qualified_rename</folder>
  <filename>15572943901</filename>
  <path>D:\Project\Lebal-Img\windows_v1.2\qualified_rename\15572943901.jpg</path>
  <source
> <database>Unknown</database> </source> <size> <width>512</width> <height>384</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>qualified</name> <
pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>107</xmin> <ymin>109</ymin> <xmax>291</xmax> <ymax>267</ymax> </bndbox> </object
> </annotation>

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

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")


轉自:https://www.cnblogs.com/soqu36/articles/9358298.html

1

python 處理xml文件