详解在 Python 中解析并修改XML内容的方法
admin
2023-07-31 00:36:13
0

需求
在实际应用中,需要对xml配置文件进行实时修改,

1.增加、删除 某些节点
2.增加,删除,修改某个节点下的某些属性
3.增加,删除,修改某些节点的文本

使用xml文档

1234567891011121314151617 xml version=\”1.0\” encoding=\”UTF-8\”??><framework>  <processers>    <processer name=\”AProcesser\” file=\”lib64/A.so\” path=\”/tmp\”/>    <processer name=\”BProcesser\” file=\”lib64/B.so\” value=\”fordelete\”/>    <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\”/>      </service>      <service name=\”update\” prefix=\”/bin/update?\”>        <chain sequency=\”chain3\” value=\”fordelete\”/>      </service>    </services>  </processers></framework>

实现思想
使用ElementTree,先将文件读入,解析成树,之后,根据路径,可以定位到树的每个节点,再对节点进行修改,最后直接将其输出

实现代码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 #!/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\”)



修改后的结果

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
python清除字符串里非数字... 本文实例讲述了python清除字符串里非数字字符的方法。分享给大家供大家参考。具体如下: impor...