xml的学习和使用python解析读取xml文件

460 阅读5分钟

1. XML的介绍

XML 指可扩展标记语言(EXtensible Markup Language)。

和json类似也是用于存储和传输数据,还可以用作配置文件。

类似于HTML超文本标记语言,但是HTML所有的标签都是预定义的,而xml的标签是自行定义。

XML 和 HTML 为不同的目的而设计,HTML 旨在显示信息,而 XML 旨在传输信息。:

XML 被设计用来传输和存储数据,其焦点是数据的内容。
HTML 被设计用来显示数据,其焦点是数据的外观。

所以对 XML 最好的描述是:

XML 是独立于软件和硬件的信息传输工具。

2.XML的树结构

XML 元素指的是从(且包括)开始标签直到(且包括)结束标签的部分。元素可包含其他元素、文本或者两者的混合物。元素也可以拥有属性。

每一个元素有三个属性:tag、text、attrib

比如下面例子中,note是根元素,他的tag就是note,attrib属性是id=1,没有文本节点,有四个子元素。

<note id="1>
    <to>Tove</to>
    <from>Jani</from>
    <heading>Reminder</heading>
    <body>Don't forget me this weekend!</body>
</note>

第一行是 XML 声明。它定义 XML 的版本(1.0)和所使用的编码(UTF-8 : 万国码, 可显示各种语言)。

第二行描述文档的根元素(像在说:"本文档是一个便签")

接下来 4 行描述根的 4 个子元素(to, from, heading 以及 body),子元素只有文本内容,元素拥有属性和元素内容。

最后一行定义根元素的结尾:

父、子以及同胞等术语用于描述元素之间的关系。父元素拥有子元素。相同层级上的子元素成为同胞。所有的元素都可以有文本内容和属性(类似 HTML 中)。

3.XML语法

在 HTML 中,某些元素不必有一个关闭标签;在 XML 中,省略关闭标签是非法的。所有元素都必须有关闭标签。

在 XML 中,XML 的属性值必须加引号。

<note date="12/11/2007">
<to>Tove</to>
<from>Jani</from>
</note>

在 HTML 中,常会看到没有正确嵌套的元素;在 XML 中,所有元素都必须彼此正确地嵌套。

<b><i>This text is bold and italic</i></b> 正确
<b><i>This text is bold and italic</b></i> 错误

XML 中的注释:

4.XML DOM

DOM(Document Object Model 文档对象模型)定义了访问和操作文档的标准方法,把 XML 文档作为树结构来查看。

所有元素可以通过 DOM 树来访问。可以修改或删除它们的内容,并创建新的元素。元素,它们的文本,以及它们的属性,都被认为是节点。

4.1python解析xml例子:

<?xml version="1.0" encoding="utf-8" ?>
<!--this is a test about xml.-->
<booklist type="science and engineering">
 <book category="math">
	 <title>learning math</title>
	 <author>张三</author>
	 <pageNumber>561</pageNumber>
 </book>
 <book category="Python">
	 <title>learning Python</title>
	 <author>李四</author>
	 <pageNumber>600</pageNumber>
 </book>
</booklist>

使用python脚本读取代码:

import os
from xml.dom.minidom import parse
 
xml_file = r'D:\pythonProject\xml\book.xml'
 
    # print(xml_file)
#获取 xml 文档对象
domTree = parse(xml_file)
#获得根节点
rootNode = domTree.documentElement
 
# print('显示xml文档内容')
# print(rootNode.toxml())
# print('*'*10)
 
#判断根节点是否有属性
if rootNode.hasAttribute('type'):
    print('根节点的的type属性为:',rootNode.getAttribute('type'))
else:
    print('根节点没有属性')
 
book=rootNode.getElementsByTagName('book')
print('有%d个book节点'%len(book))
 
print(rootNode.getElementsByTagName('title')[0].childNodes[0].nodeValue)
print("rootNode.getElementsByTagName('title')[0] 是获取文档第一个title元素")
print("childNodes[0]是‘title'元素的第一个子元素,也就是文本节点")
print("nodeValue为获取节点的值")
 
print('*'*10)
 
for i in range(len(book)):
    print('\n显示第%d个book节点的内容:'%(i+1))
    print(rootNode.getElementsByTagName('book')[i].toxml())
    print()
    if rootNode.getElementsByTagName('book')[i].hasAttribute('category'):
            print('book节点的属性是:',book[i].getAttribute('category'))
        
    print('title的值:',book[i].getElementsByTagName('title')[0].childNodes[0].data)
    #从根节点写是print(rootNode.getElementsByTagName('book')[1].getElementsByTagName('title')[0].childNodes[0].data)
    
    print('author的值:',book[i].getElementsByTagName('author')[0].childNodes[0].data)
    #或者用childNodes[0].nodeValue
    # print('author的值:', book[i].getElementsByTagName('author')[0].childNodes[0].nodeValue)
    
    print('pageNumber的值:',book[i].getElementsByTagName('pageNumber')[0].childNodes[0].data)
    print('*' * 10)
 

image.png

其中需要注意的是即使 XML 文件只包含一个元素,也必须指定数组索引 [0]。这是因为getElementsByTagName() 方法返回的是一个数组。

4.2python创建xml例子

doc.writexml():生成xml文档,将创建的存在于内存中的xml文档写入本地硬盘中,这时才能看到新建的xml文档

语法: writexml(file,indent=’’,addindent=’’,newl=’’,endocing=None)

参数说明: file:要保存为的文件对象名 indent:根节点的缩进方式 allindent:子节点的缩进方式 newl:针对新行,指明换行方式 encoding:保存文件的编码方式

import xml.dom.minidom
 
#在内存中创建一个空的文档
doc=xml.dom.minidom.Document()
 
#创建根元素
root=doc.createElement('booklist')
# print('添加的xml标签为:',root.tagName)
 
#设置根元素的属性
root.setAttribute('type','science and engineering')
 
#将根节点添加到文档对象中
doc.appendChild(root)
 
#创建子元素
book=doc.createElement('book')
#添加注释
book.appendChild(doc.createComment('这是注释'))
 
#设置子元素的属性
book.setAttribute('category','math')
 
#子元素中嵌套子元素,并添加文本节点
title=doc.createElement('title')
title.appendChild(doc.createTextNode('learning math'))
author=doc.createElement('author')
author.appendChild(doc.createTextNode('张三'))
pageNumber=doc.createElement('pageNumber')
pageNumber.appendChild(doc.createTextNode('561'))
 
#将子元素添加到boot节点中
book.appendChild(title)
book.appendChild(author)
book.appendChild(pageNumber)
#将book节点添加到root根元素中
root.appendChild(book)
 
#创建子元素
book=doc.createElement('book')
#设置子元素的属性
book.setAttribute('category','python')
 
title=doc.createElement('title')
title.appendChild(doc.createTextNode('learning python'))
 
author=doc.createElement('author')
author.appendChild(doc.createTextNode('李四'))
pageNumber=doc.createElement('pageNumber')
pageNumber.appendChild(doc.createTextNode('600'))
 
#将子元素添加到boot节点中
book.appendChild(title)
book.appendChild(author)
book.appendChild(pageNumber)
#将book节点添加到root根元素中
root.appendChild(book)
 
print(root.toxml())
 
fp= open(r'D:\pythonProject\xml\new.xml','w',encoding='utf-8')#需要指定utf-8的文件编码格式,不然notepad中显示十六进制
doc.writexml(fp,indent='',addindent='\t',newl='\n',encoding='utf-8')
fp.close()

运行显示结果:

image.png

 4.3向xml中插入新的子元素

import os
import xml.dom.minidom
 
from xml.dom.minidom import parse
 
#对book.xml新增一个子元素english,并删除math元素
xml_file = r'D:\pythonProject\xml\book.xml'
 
# #拿到根节点
domTree = parse(xml_file)
rootNode = domTree.documentElement
 
rootNode.removeChild(rootNode.getElementsByTagName('book')[0])
 
print(rootNode.toxml())
 
#在内存中创建一个空的文档
doc=xml.dom.minidom.Document()
 
book=doc.createElement('book')
book.setAttribute('category','english')
title=doc.createElement('title')
title.appendChild(doc.createTextNode('learning english'))
author=doc.createElement('author')
author.appendChild(doc.createTextNode('王五'))
pageNumber=doc.createElement('pageNumber')
pageNumber.appendChild(doc.createTextNode('328'))
 
book.appendChild(title)
book.appendChild(author)
book.appendChild(pageNumber)
 
math_book=rootNode.getElementsByTagName('book')[0]
 
#insertBefore方法  父节点.insertBefore(新节点,父节点中的子节点)
rootNode.insertBefore(book,math_book)
#appendChild将新产生的子元素在最后插入
# rootNode.appendChild(book)
 
print(rootNode.toxml())
 
with open(xml_file,'w',encoding='utf-8') as fh:
    domTree.writexml(fh,indent='',addindent='\t',newl='',encoding='utf-8')

运行后显示效果:

image.png