当前位置:   article > 正文

python读写XML(20201217)_toprettyxml

toprettyxml

XML指可扩展标记语言(eXtensible Markup Language), 被设计用来传输和存储数据。python中有三个模块解析xml文件:DOM, ElementTree,SAX。

 

三个工具包

1、DOM(Document Object Model)

DOM是个跨平台的标准模型,W3C定义了DOM模型里的概念。DOM将XML数据在内存中解析成一个树,通过对树的操作来操作XML。python的xml.dom.minimom模块实现了DOM

1.1  DOM写入xml文件

DOM写入xml文件主要是创建dom树,然后创建根结点,创建子节点并加入到根节点,最后将整个dom树写入文件,相关API如下:

  1. DOM写入相关API
  2. doc = minidom.Document() #创建树
  3. doc.createElement("folder") #创建名为folder的结点
  4. doc.createTextNode('user') #创建文本结点,文本为 user
  5. root_node.appendChild(folder_node) #root_node结点添加folder_node为子节点book_node.setAttribute('price','199') #book_node设置属性值
  6. # 每一个结点对象(包括dom对象本身)都有输出XML内容的方法,如:toxml()--字符串, toprettyxml()--美化树形格式。 doc.toxml(encoding="utf-8") # 输出字符串 doc.toprettyxml(indent='', addindent='\t', newl='\n', encoding="utf-8")) #输出带格式的字符串 doc.writexml() #将prettyxml字符串写入文件

1.2 例子

  1. def write_xml():
  2. #1. 创建dom树对象
  3. doc = minidom.Document()
  4. #2. 创建根结点,并用dom对象添加根结点
  5. root_node = doc.createElement("annotation")
  6. doc.appendChild(root_node)
  7. #3. 创建结点,结点包含一个文本结点, 再将结点加入到根结点
  8. folder_node = doc.createElement("folder")
  9. folder_value = doc.createTextNode('user')
  10. folder_node.appendChild(folder_value)
  11. root_node.appendChild(folder_node)
  12. filename_node = doc.createElement("filename")
  13. filename_value = doc.createTextNode('0000001.jpg')
  14. filename_node.appendChild(filename_value)
  15. root_node.appendChild(filename_node)
  16. path_node = doc.createElement("path")
  17. path_value = doc.createTextNode('/home')
  18. path_node.appendChild(path_value)
  19. root_node.appendChild(path_node)
  20. source_node = doc.createElement("source")
  21. database_node = doc.createElement("database")
  22. database_node.appendChild(doc.createTextNode("Unknown"))
  23. source_node.appendChild(database_node)
  24. root_node.appendChild(source_node)
  25. size_node = doc.createElement("size")
  26. for item, value in zip(["width", "height", "depth"], [1920, 1080, 3]):
  27. elem = doc.createElement(item)
  28. elem.appendChild(doc.createTextNode(str(value)))
  29. size_node.appendChild(elem)
  30. root_node.appendChild(size_node)
  31. seg_node = doc.createElement("segmented")
  32. seg_node.appendChild(doc.createTextNode(str(0)))
  33. root_node.appendChild(seg_node)
  34. obj_node = doc.createElement("object")
  35. name_node = doc.createElement("name")
  36. name_node.appendChild(doc.createTextNode("boat"))
  37. obj_node.appendChild(name_node)
  38. pose_node = doc.createElement("pose")
  39. pose_node.appendChild(doc.createTextNode("Unspecified"))
  40. obj_node.appendChild(pose_node)
  41. trun_node = doc.createElement("truncated")
  42. trun_node.appendChild(doc.createTextNode(str(1)))
  43. obj_node.appendChild(trun_node)
  44. trun_node = doc.createElement("difficult")
  45. trun_node.appendChild(doc.createTextNode(str(0)))
  46. obj_node.appendChild(trun_node)
  47. bndbox_node = doc.createElement("bndbox")
  48. for item, value in zip(["xmin", "ymin", "xmax", "ymax"], [103, 1, 634, 402]):
  49. elem = doc.createElement(item)
  50. elem.appendChild(doc.createTextNode(str(value)))
  51. bndbox_node.appendChild(elem)
  52. obj_node.appendChild(bndbox_node)
  53. root_node.appendChild(obj_node)
  54. with open("0000001.xml", "w", encoding="utf-8") as f:
  55. # 4.writexml()第一个参数是目标文件对象,第二个参数是根节点的缩进格式,第三个参数是其他子节点的缩进格式,
  56. # 第四个参数制定了换行格式,第五个参数制定了xml内容的编码。
  57. doc.writexml(f, indent='', addindent='\t', newl='\n', encoding="utf-8")
  58. # 每一个结点对象(包括dom对象本身)都有输出XML内容的方法,如:toxml()--字符串, toprettyxml()--美化树形格式。
  59. # print(doc.toxml(encoding="utf-8")) # 输出字符串
  60. # print(doc.toprettyxml(indent='', addindent='\t', newl='\n', encoding="utf-8")) #输出带格式的字符串
  61. # doc.writexml() #将prettyxml字符串写入文件
  62. 写入xml文件

1.3 读取和更新XML文件

解析xml文件为DOM树,获取树的根节点,随后即可通过根节点寻找相关的子节点,并获取相关的属性和文本,相关API如下:

  1. 读取xml的API
  2. doc = minidom.parse(xml_path) #解析xml文件(句柄或文件路径)
  3. doc = minidom.parseString() #解析xml字符串
  4. root_node = doc.documentElement #获得根节点
  5. print(root_node.nodeName) #结点名称
  6. print(root_node.nodeType) #结点类型 (元素结点,文本结点,属性结点)
  7. print(root_node.childNodes) #所有子节点,为列表
  8. print(node.parentNode) # 获取父节点
  9. filename_node = root_node.getElementsByTagName('filename')[0] #通过结点名称寻找结点,返回列表#文本结点
  10. filename = filename_node.childNodes[0].data #子节点为文本结点,文本结点有data属性即为文本值
  11. #属性结点
  12. # node.getAttribute('price') #属性结点node,获取其price属性

  下面为一个读取xml文件并更新指定结点文本值的代码:

  1. def read_xml(xml_path):
  2. with open(xml_path, "r", encoding="utf-8") as f:
  3. doc = minidom.parse(xml_path) #解析xml文件(句柄或文件路径)
  4. #doc = minidom.parseString() #解析xml字符串
  5. root_node = doc.documentElement #获得根节点
  6. #找到xmin结点并更新其对应的文本值
  7. xmin_node = root_node.getElementsByTagName("xmin")[0]
  8. print(xmin_node.childNodes[0].data)
  9. xmin_node.childNodes[0].data = str(200)
  10. print(xmin_node.childNodes[0].data)
  11. with open(xml_path, "w", encoding="utf-8") as f:
  12. doc.writexml(f)
'
运行

 2、ElementTree()

轻量级DOM,python专有,使用起来更加简单,常用API如下:

读取和解析xml文件

支持遍历结点,查找结点和访问结点,如下图所示;

2.1 读取和解析xml文件

  1. def element_read_xml(xml_path):
  2. #1. 获取root结点
  3. tree = ET.parse(xml_path) #方式一
  4. root = tree.getroot()
  5. # tree = ET.ElementTree(file=xml_path) # 方式二
  6. # root = tree.getroot()
  7. # with open(xml_path, "r", encoding="utf-8") as f: # 方式三
  8. # root = ET.fromstring(f.read())
  9. print(root)
  10. #2.访问特定结点属性 (属性包括tag, text, attrib)
  11. #遍历结点, 每一个结点都是一个迭代器,能遍历其子节点
  12. for i in root:
  13. print(i.tag, i.attrib)
  14. for j in i:
  15. print(j, j.attrib)
  16. #3.下标方式访问子节点
  17. print(root[0].tag, root[0].attrib, root[0].text)
  18. #4. 查找结点,支持tag名字和xpath语法
  19. print(tree.find("folder")) #在当前结点的子节点中寻找标签为folder的子节点
  20. print(tree.find(".//name")) #寻找所有子孙结点中第一个标签为name的子节点
  21. print(tree.findall(".//name")) #寻找所有子孙结点中标签为name的子节点(返回列表)
  22. print(tree.findtext(".//name")) #寻找所有子孙结点中第一个标签为name的子节点,并返回其text属性
'
运行

 2.2 创建xml文件并写入

需要创建根节点,然后添加子节点,最后创建节点树并写入,如下所示:

  1. def write_xml():
  2. root = ET.Element("node")
  3. folder_node = ET.Element("folder")
  4. folder_node.text = "/home"
  5. folder_node.tail = "\n"
  6. print(dir(folder_node))
  7. root.append(folder_node) #添加子节点
  8. #extend(subments) #添加多个子节点
  9. elem3 = ET.Element("test_extend")
  10. elem3.text = "elem 3"
  11. elem3.tail = "\n" #结点尾部添加换行
  12. elem4 = ET.Element("test_extend")
  13. elem4.text = "elem 4"
  14. elem4.tail = "\n"
  15. root.extend([elem3, elem4])
  16. #insert(index, subment) #插入子节点
  17. #remove(subment) #删除子节点
  18. folder_node = ET.SubElement(root, "folder") # 为root添加子节点
  19. folder_node.text = "/home"
  20. tree = ET.ElementTree(root)
  21. tree.write("output.xml", encoding="utf-8", xml_declaration=True) #保存时无缩进,添加缩进需要借用dom
  22. #借用dom,添加缩进
  23. # rawtext = ET.tostring(root)
  24. # dom = minidom.parseString(rawtext)
  25. # with open("output.xml", "w") as f:
  26. # dom.writexml(f, indent="\t", newl="", encoding="utf-8")
'
运行

2.3 读取并更新节点

  1. def update_xml():
  2. #查找节点并更新
  3. root = ET.parse("output.xml")
  4. for node in root.findall(".//folder"):
  5. if node.text == "/home":
  6. node.tag = "path"
  7. ET.dump(root) #打印xml
  8. root.write("output.xml")
'
运行

SAX(Simple API for XML)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/1003801
推荐阅读
相关标签
  

闽ICP备14008679号