elementTree解析并修改xml文件实例

可以查看官方文档,里面给的内容给得挺详尽,下面是我自己总结的一些常用的封装函数

Element.findall(‘tag’):仅查找具有标记的元素,这些元素是当前元素的直接子元素。
Element.find('tag'): 找到具有特定标记的第一个子项 
Element.text: 获取元素的内容
Element.get(): 获取元素的属性

修改元素属性以及内容的操作:
以例子来说明:
for rank in root.iter('rank'):        //通过迭代找出根元素的子元素中标签为rank的元素
...     new_rank = int(rank.text) + 1//修改rank的内容,使其加1
...     rank.text = str(new_rank)     //注意内容类型的转换,加减用int,存储用string
...     rank.set('updated', 'yes')    //给rank添加属性:uodated=yes

Element.remove():删除某个节点元素
以例子来说明:
for country in root.findall('country'):      //遍历所有标签为country的节点
...     rank = int(country.find('rank').text)//获得country的子节点rank的内容
...     if rank > 50:                        //内容大于50
...         root.remove(country)             //将包含该rank节点的country节点删除
...

以下例子来自于别人博客的例子,代码很详细,包括了从读入xml文件到节点的增删查改操作几乎齐全,有一个缺点:此处的读取xml文件考虑的是最简单的文件较小,且在本地直接读取;有一些工程需要在客户端和服务端交互xml文件时,此时如果将整个xml文件接收完全再来进行操作容易导致堵塞。所以在官方文档里提到用treebuilder和另一种方法来解决。

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

#!/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")

操作对象(原始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 version='1.0' encoding='utf-8'?>  
<framework>  
    <processers>  
        <processer file="lib64/A.so" name="AProcesser" path="/tmp">  
        </processer>  
        <processer age="1" file="lib64/B.so" name="BProcesser">  
            <person age="15" money="200000">this is the firest content</person>  
        </processer>  
        <processer age="1" file="lib64/B.so2222222" name="BProcesser">  
            <person age="15" money="200000">this is the firest content</person>  
        </processer>
 
        <services>  
            <service name="search" output_formatter="OutPutFormatter:service_inc"  
                prefix="/bin/search?">
 
                <chain sequency="chain2" />  
            </service>  
            <service name="update" prefix="/bin/update?">  
                <chain sequency="chain3" value="fordelete">new text</chain>  
            </service>  
        </services>  
    </processers>  
</framework>

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值