• python处理xml文件


    一、python 操作xml的方式介绍

        查看全部包含“三种⽅法:
        ⼀是xml.dom. * 模块,它是W3CDOMAPI的实现,若需要处理DOMAPI则该模块很适合;
        ⼆是xml.sax. * 模块,它是SAXAPI的实现,这个模块牺牲了便捷性来换取速度和内存占⽤,SAX是⼀个基于事件的API,这就意味着它可以“在空中”处理庞⼤数量的的⽂档,不⽤完全加载进内存;
        三是xml.etree.ElementTree模块(简称 ET),它提供了轻量级的Python式的API,相对于DOM来说ET 快了很多,⽽且有很多令⼈愉悦的API可以使⽤,相对于SAX来说ET的ET.iterparse也提供了 “在空中” 的处理⽅式,没有必要加载整个⽂档到内存,ET的性能的平均值和SAX差不多,但是API的效率更⾼⼀点⽽且使⽤起来很⽅便。

    使用 xml.dom. * 模块:

    1. from xml.dom.minidom import Document
    2. #创建一个文本
    3. doc = Document()
    4. #创建一个父节点
    5. root = doc.createElement("root")
    6. #父节点加入文本
    7. doc.appendChild(root)
    8. #创建一个子节点
    9. head = doc.createElement("head")
    10. #子节点加入父节点
    11. root.appendChild(head)
    12. #创建一个属性
    13. text1 = doc.createTextNode("1")
    14. #创建一个子节点
    15. code = doc.createElement("code")
    16. #子节点加入父节点
    17. code.appendChild(text1)
    18. #子节点加入前子节点
    19. head.appendChild(code)
    20. #打印一下xml
    21. print doc.toxml()
    22. #上述输出节点输出为
    23. #<?xml version="1.0" ?><root><head><code>1</code></head></root>
    24. text2 = doc.createTextNode("2")
    25. Msg = doc.createElement("Msg")
    26. Msg.appendChild(text2)
    27. head.appendChild(Msg)
    28. #print doc.toxml()
    29. #输出文件
    30. with open("testq.arxml","w+") as f:
    31. #文件转码decode是为了保证输出的是UTF-8格式
    32. f.write(doc.toprettyxml(encoding = "UTF-8").decode("UTF-8"))
    33. f.close()

    原文:Python学习(十四):Python如何创建一个xml文件_python生成xml文件-CSDN博客

    最常用的是xml.etree.ElementTree模块。

    二、ElementTree模块

    2.1 解析xml文件,获取根节点,并读取节点内容

    注意xml格式的内容应该没有xml格式声明的内容“”,如果有则会解析错误

    1. from xml.etree import ElementTree as ET
    2. # 1、打开xml文件
    3. tree =ET.parse(r"E:\testData\yy001.xml")
    4. # 获xml文件的内容取根标签
    5. root = tree.getroot()
    6. # 2、读取节点内容
    7. # 2.1 获取根标签下的子标签
    8. for child in root: 获取根节点下的子标签
    9. print(child.tag) # *.tag 是获取标签名字(字符串类型)
    10. print( child.attrib) # *.attrib是获取标签属性(字典类型)
    11. for node in child: 获取跟标签下子标签的子标签
    12. print(node.tag)
    13. print(node.attrib)
    14. print(node.text) # *.text 获取标签文本
    2.2 通标标签名直接获取标签(find,findall)

    find()  此方法只能获取当前标签的下一级子标签,不能查询到下一级的下一级标签,且找到的是第一个相应的标签
    findall() 此方法只能获取当前标签的下一级子标签,不能查询到下一级的下一级标签,但是找到下一级的所有符合名称的标签

    2.3全文搜索标签名(类似xpath路径查找标签)
    1. # 1、打开xml文件
    2. from xml.etree import ElementTree as ET
    3. tree = ET.parse(r"E:\testData\yy01.xml")
    4. # 获xml文件的内容取根标签
    5. root = tree.getroot()
    6. #print(root)
    7. # 2.1 通过标签名称获取标签 find()
    8. events_object = root.find("Events") # 此种写法只能获取根标签下的一级子标签,即只能查询下一级标签,不能查询到下一级的下一级标签,**且找到的是第一个响应的标签**
    9. print(events_object.tag, events_object.attrib)
    10. event_object = events_object.find("Event") # 进一步获取跟标签下子标签的子标签
    11. print(event_object.tag,event_object.attrib)
    12. # 2.2 通过标签名称获取标签 findall()
    13. events_objects = root.findall("Events") # 此种写法只能获取根标签下的一级子标签,即只能查询下一级标签,不能查询到下一级的下一级标签,但是可以获取下一级所有符合名称的标签
    14. for event_clee in events_objects:
    15. print(event_clee.tag, event_clee.attrib)
    16. event_object = event_clee.findall("Event") # 进一步获取跟标签下子标签的子标签
    17. for relation_cell in event_object:
    18. print(relation_cell.tag, relation_cell.attrib)
    19. # 2.3 findall(xpath)
    20. Events_object = root.findall('.//Code')
    21. Events_object1 = root.findall('.//Code[@curCode="010697059381010910N053000117230527"]')
    22. Events_object2 = root.findall('.//*[@curCode="010697059381010910N053000117230527"]')
    23. #注意 前面的“.”不能省略,
    24. print(Events_object)
    25. print(Events_object1)
    26. print(Events_object2[0])
    27. # 2.4 全文搜索标签名为“Code”的标签
    28. Code_object = root.iter("Code") 全文搜索标签名为“Code”的标签
    29. print(Code_object)
    30. for code in Code_object:
    31. print(code.tag, code.attrib)
    2.4 修改和删除节点
    1. tree =ET.parse(r"E:\testData\yy01.xml")
    2. root = tree.getroot()
    3. #修改
    4. relation_object = root.find("Events").find("Event").iter("Relation") # 获取第一个Events的一级子标签下的Relation子标签
    5. for relation_cell in relation_object:
    6. relation_cell.set("productCode", "产品编码") # 如果有相应属性,则修改属性值,没有则新增
    7. relation_cell.set("productCode2", "产品编码2")
    8. relation_cell.find("Batch").find("Code").text="追溯码" # 注意:如果之前是短标签,增加文本属性后自动变为长标签。
    9. # tree = ET.ElementTree(root)
    10. tree.write("new.xml", encoding="utf-8",short_empty_elements=True) # 如果文件不存在,则创建文件,如果文件已存在则修改响应内容
    11. -------------------------------------------------------------------------------------------------
    12. #删除
    13. root = tree.getroot()
    14. # ####################错误的删除方式########################
    15. # # 获取响应标签
    16. # Event_object = root.find("Events").find("Event")
    17. # # 删除相应标签
    18. # root.remove(Event_object) # 删除只能删除其子标签,不能删除其子标签下的子标签,因为relation_object是子标签下的子标签,因此此时删除失败
    19. ################## 正确的删除方式#############################
    20. Events_object = root.find("Events")
    21. Event_object = Events_object.find("Event")
    22. Events_object.remove(Event_object)
    23. # tree = ET.ElementTree(root)
    24. tree.write("new.xml", encoding="utf-8") # 如果文件不存在,则创建文件,如果文件已存在则修改响应内容
    注意:tree.write("newCreate.xml", xml_declaration=True,  encoding="utf-8", short_empty_elements=True)
    # xml_declaration是否包含声明文件, encoding编码方式,short_empty_elements 规定是短标签(单标签)还是双标签

    三、构建文件【xml中换行需要做特殊处理,默认都是在同一行】

    方式1 (Element)

    先创建各类标签,再建立标签之间关系

    1. from xml.etree import ElementTree as ET
    2. # 创建根标签
    3. root = ET.Element("root")
    4. # 创建一个标签tagName1
    5. tagName1 = ET.Element("tagName1", {"tag1Attribute":"AttributeValue1"})
    6. # 创建一个标签tagName2
    7. tagName2 = ET.Element("tagName2", {"tag2Attribute":"AttributeValue2"})
    8. # 创建一个标签tagName11
    9. tagName11 = ET.Element("tagName11", {"tag11Attribute":"AttributeValue11"})
    10. # 创建一个标签tagName12
    11. tagName12 = ET.Element("tagName12", {"tag12Attribute":"AttributeValue12"})
    12. # 将标签tagName11和tagName12 添加的tagName1中作为tagName1的子标签
    13. tagName1.append(tagName11)
    14. tagName1.append(tagName12)
    15. # 将标签tagName1和tagName2 添加的root中作为root的子标签
    16. root.append(tagName1)
    17. root.append(tagName2)
    18. # 保存
    19. tree = ET.ElementTree(root)
    20. tree.write("newCreate.xml", xml_declaration=True, encoding="utf-8",short_empty_elements=True)
    21. # xml_declaration是否包含声明文件, encoding编码方式,short_empty_elements 规定是短标签(单标签)还是双标签
    1. <root>
    2. <tagName1 tag1Attribute="AttributeValue1">
    3. <tagName11 tag11Attribute="AttributeValue11"/>
    4. <tagName12 tag12Attribute="AttributeValue12"/>
    5. tagName1>
    6. <tagName2 tag2Attribute="AttributeValue2"/>
    7. root>

    方式2 (makeelement)

    1. from xml.etree import ElementTree as ET
    2. # 创建根节点
    3. root = ET.Element("family")
    4. # 创建一级子标签
    5. son1 = root.makeelement("son", {"name":"son1"})
    6. son2 = root.makeelement("son", {"name":"son2"})
    7. # 创建二级子标签
    8. grandson1 = son1.makeelement("grandson1", {"name":"grandson1"})
    9. grandson2 = son1.makeelement("grandson1", {"name":"grandson2"})
    10. # 将二级子标签与一级子标签关联
    11. son1.append(grandson1)
    12. son1.append(grandson2)
    13. # 将一级子标签与根标签关联
    14. root.append(son2)
    15. root.append(son1)
    16. tree = ET.ElementTree(root)
    17. tree.write("../testData/neswfile.xml", xml_declaration=True, encoding="utf-8", short_empty_elements=False)
    1. <family>
    2. <son name="son2">son>
    3. <son name="son1">
    4. <grandson1 name="grandson1">grandson1>
    5. <grandson1 name="grandson2">grandson1>
    6. son>
    7. family>

    方式3

    此种方式是在创建元素时直接建立相关关系

    1. from xml.etree import ElementTree as ET
    2. # 创建根节点
    3. root = ET.Element("family")
    4. # 创建一级子标签
    5. son1 = ET.SubElement(root, "son", {"name":"son1"})
    6. son2 = ET.SubElement(root,"son", {"name":"son2"})
    7. # 创建二级子标签
    8. grandson1 = ET.SubElement(son1,"grandson1", {"name":"grandson1"})
    9. grandson1.text="大孙子"
    10. grandson2 = ET.SubElement(son1,"grandson1", {"name":"grandson2"})
    11. grandson2.text="小孙子"
    12. tree = ET.ElementTree(root)
    13. tree.write("../testData/neswfile.xml", xml_declaration=True, encoding="utf-8")
    1. <family>
    2. <son name="son1">
    3. <grandson1 name="grandson1">大孙子grandson1>
    4. <grandson1 name="grandson2">小孙子grandson1>
    5. son>
    6. <son name="son2"/>
    7. family>

    根据xsd生成xml文件

    1. import xmlschema
    2. import json
    3. from xml.etree.ElementTree import ElementTree
    4. my_xsd = ' '
    5. schema = xmlschema.XMLSchema(my_xsd)
    6. data = json.dumps({'note': 'this is a Note text'})
    7. xml = xmlschema.from_json(data, schema=schema, preserve_root=True)
    8. ElementTree(xml).write('my_xml.xml')

    对于更复杂的 xsd,我更喜欢使用 generateDS,它甚至可以为非常大的 xsd 文件创建非常非常可靠的类.
    原文链接:https://blog.csdn.net/Mwyldnje2003/article/details/125819447

    四、处理换行问题

    1. def prettyXml(element, indent, newline, level=0):
    2. '''
    3. 参数:
    4. elemnt为传进来的Elment类;
    5. indent用于缩进;
    6. newline用于换行;
    7. '''
    8. # 判断element是否有子元素
    9. if element:
    10. # 如果element的text没有内容
    11. if element.text == None or element.text.isspace():
    12. element.text = newline + indent * (level + 1)
    13. else:
    14. element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * (level + 1)
    15. # 此处两行如果把注释去掉,Element的text也会另起一行
    16. # else:
    17. # element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * level
    18. temp = list(element) # 将elemnt转成list
    19. for subelement in temp:
    20. # 如果不是list的最后一个元素,说明下一个行是同级别元素的起始,缩进应一致
    21. if temp.index(subelement) < (len(temp) - 1):
    22. subelement.tail = newline + indent * (level + 1)
    23. else: # 如果是list的最后一个元素, 说明下一行是母元素的结束,缩进应该少一个
    24. subelement.tail = newline + indent * level
    25. # 对子元素进行递归操作
    26. prettyXml(subelement, indent, newline, level=level + 1)
    27. tree = ET.parse('filename')
    28. root = tree.getroot()
    29. root.set('xmlns', 'http://ts.szse.cn/Fund')
    30. prettyXml(root, '\t', '\n')

  • 相关阅读:
    Linux 基本语句_6_C语言_文件操作
    信息技术服务标准是什么
    【Numpy基础(01)NumPy数组的构造】
    【C++ Primer Plus学习记录】数组的替代品vector、array
    金九银十“吃透”这份大厂Java面试题+答案解析,直接成功上岸拿到offer!
    YOLOV5算法二之数据集转换及自动划分训练集与测试集
    C++ std map unordered_map hash_map 的查找性能测试代码及结果
    简述电子企业MES管理系统解决方案的实施策略
    (更新中)深入浅出操作系统 - 目录
    You have an error in your SQL syntax; check the manual that corresponds to...
  • 原文地址:https://blog.csdn.net/a963241242/article/details/134460745