• Python实现XML的操作


    本文从以下两个方面, 用Python实现XML的操作:

    一. minidom写入XML示例1

    二. minidom写入XML示例2

    三. ElementTree写入/修改示例

    四. ElementTree读取/修改/写入示例

     

    一. minidom写入XML示例1

    1.引入包

    import xml.dom.minidom

    2.write XML方法

    writexml(writer, indent, addindent, newl, encoding)
     
    writer是文件对象
    indent是每个tag前填充的字符,如:'  ',则表示每个tag前有两个空格
    addindent是每个子结点的缩近字符,如下面的例子中单引号中我直接用的tab键
    newl是每个tag后填充的字符,如:'
    ',则表示每个tag后面有一个回车
    encoding是生成的XML信息头中的encoding属性值,在输出时minidom并不真正进行编码的处理,如果你保存的文本内容中有汉字,则需要自已进行编码转换。

    3.Python代码

    #xmlTest_write.py
    # -*- coding: utf-8 -*-
     
    import xml.dom.minidom
     
    #生成xml文件
    def GenerateXml():
        impl = xml.dom.minidom.getDOMImplementation()
        #设置根结点emps
        dom = impl.createDocument(None, 'emps', None)
        root = dom.documentElement
        employee = dom.createElement('emp')
     
        #增加属性
        employee.setAttribute("empno","1111")
        root.appendChild(employee)
     
        #设置子结点
        #ename
        nameE=dom.createElement('ename')
        nameT=dom.createTextNode('杰克')
        nameE.appendChild(nameT)
        #子节点添加属性
        nameE.setAttribute("lastname","")
     
        employee.appendChild(nameE)
        #age
        nameE=dom.createElement('age')
        nameT=dom.createTextNode('33')
        nameE.appendChild(nameT)
     
        employee.appendChild(nameE)
     
        f= open('emplist.xml', 'w') #w替换为a,追加
        dom.writexml(f, addindent=' ', newl='
    ')
        f.close()
     
    GenerateXml()

    4.写入XML结果

    <?xml version="1.0" ?>
    <emps>
        <emp empno="1111">
            <ename lastname="">杰克</ename>
            <age>33</age>
        </emp>
    </emps>

    二. minidom写入XML示例2

    1.Python代码

    #Python写xml比较简单,直接使用xml模块的minidom即可对xml文件进行写入操作
        from xml.dom.minidom import Document
        doc = Document()
        people = doc.createElement("people")
        doc.appendChild(people)
        aperson = doc.createElement("person")
        people.appendChild(aperson)
        name = doc.createElement("name")
        aperson.appendChild(name)
        personname = doc.createTextNode("Annie")
        name.appendChild(personname)
        filename = "people.xml"
        f = open(filename, "w")
        f.write(doc.toprettyxml(indent="  "))
        f.close()

    2. 写入XML结果

    <?xml version="1.0" ?>
    <people>
      <person>
        <name>Annie</name>
      </person>
    </people>

    三. ElementTree写入/修改XML示例

    1.写入XMl的Python代码

    #coding=utf-8
    import xml.etree.ElementTree as ET
    #创建根节点
    root = ET.Element("root")
    #创建root的子节点sub1,并添加属性
    firstNode = ET.SubElement(root,"sub1")
    firstNode.attrib = {"name":"name attribute","age":"age attribute"}
    #创建子节点1(sub1)的子节点sub2,并添加数据
    secondNode = ET.SubElement(firstNode,"sub2")
    secondNode.text = "test"
    #创建elementtree对象,写文件
    tree = ET.ElementTree(root)
    tree.write("test01.xml")

    2. 写入XML结果

    <root>
        <sub1 age="age attribute" name="name attribute">
            <sub2>test</sub2>
        </sub1>
    </root>

    3. 修改XML方法

    1. ElementTree.write("xmlfile"):更新xml文件
    2. Element.append():为当前element对象添加子元素(element)
    3. Element.set(key,value):为当前element的key属性设置value值
    4. Element.remove(element):删除为element的节点

    4. 修改XML的Python代码

    #coding=utf-8
    import xml.etree.ElementTree as ET
    #读取待修改文件
    updateTree = ET.parse("test.xml")
    root = updateTree.getroot()
    #创建新节点并添加为root的子节点
    newEle = ET.Element("NewElement")
    newEle.attrib = {"name":"NewElement","age":"20"}
    newEle.text = "This is a new element"
    root.append(newEle)
     
    #修改sub1的name属性
    sub1 = root.find("sub1")
    sub1.set("name","New Name")
     
    #修改sub2的数据值
    sub2 = root.find("sub1/sub2")
    sub2.text = "New Value"
     
    #写回原文件
    updateTree.write("test.xml")

    5. 修改XML结果

    <root>
        <sub1 age="age attribute" name="New Name">
            <sub2>New Value</sub2>
        </sub1>
        <NewElement age="20" name="NewElement">This is a new element</NewElement>
    </root>

     

    四. ElementTree读取/修改/写入示例

    1. 原始文档内容(test.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>

    2. Python操作xml代码:

    # -*- coding:utf-8 -*-
    '''
    Created on 2018年8月30日
    @author: Administrator
    '''
    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("D://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, "D://xiugai.xml")

    3.更改之后的内容(xiugai.xml):

    <?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>

    参考文章:

    https://docs.python.org/3.5/library/xml.dom.minidom.html
    https://docs.python.org/3.5/library/xml.etree.elementtree.html
    https://blog.csdn.net/Tcorpion/article/details/75247168?locationNum=8&fps=1
    https://blog.csdn.net/tcorpion/article/details/75244681
    https://blog.csdn.net/weixin_39909877/article/details/78852287
    https://www.jb51.net/article/146558.htm

  • 相关阅读:
    Entity Framework在Asp.net MVC中的实现One Context Per Request(转)
    Entity Framework中的Identity map和Unit of Work模式(转)
    hudi
    拉链表和流水表
    onedata
    window.top 踩坑前车之鉴
    识别RESTful API资源
    就是不想用if
    如何在面试中评估一个BA的能力
    Python逻辑运算结果的类型
  • 原文地址:https://www.cnblogs.com/huzixia/p/10391956.html
Copyright © 2020-2023  润新知