Python处理XML文件

目录

  • 前言
  • 准备
  • xml.dom对象
    • 1. Document
    • 2. Node
    • 3. NodeList
    • 4. Element
    • 5. Attr
  • 解析xml文档
    • 1.查找内容
      • 1.1 获取根元素:
      • 1.2 查找子元素:
      • 1.3 获取元素的属性:
      • 1.4 获取文本
    • 2. 增加内容
    • 3. 删除内容
    • 4. 更新属性
  • 创建xml文档

前言

XML全称是Extensible Markup Language,中文名为可扩展标记语言。对xml的介绍可以看一下w3c的介绍。网络中数据传输的常见格式有json、xml、txt等。json很简单,xml稍微复杂,但是在python面前都不是事。
python有三种方式解析xml文档:SAX,DOM,以及 ElementTree(引自 菜鸟教程-Python XML解析),sax有些复杂,dom简单但是解析速度上不如sax。但是咱就是说,都选择Python了,肯定是想“更简单”。所以本文主要介绍python通过DOM方式对xml文件的解析读取、创建、修改等操作。
python有内置的模块:xml.dom(xml.dom官方文档)和xml.dom.minidom(xml.dom.minidom官方文档),本文主要使用xml.dom.minidom这个内置模块。


准备

xml.dom.minidom是dom的最小实现方式。以下是在python文件中需要导入的代码:

from xml.dom import minidom

xml.dom对象

众所周知,python是面向对象的,xml.dom解析xml文档之后会返回一系列对象,对对象的操作来获取信息。
xml.dom解析xml文件,将文件内容解析为DOM,以下是常见的dom中的对象:

对象 解释
DOMImplementation 创建新的xml时有用
Node 节点对象,文档中大多数对象的基本接口。像Element,Attr,Comment都继承自Node
NodeList 节点列表对象,一系列节点的接口。
DocumentType 文档类型对象,有关处理文档所需的声明的信息。
Document 文档对象,表示整个文档的对象。
Element 元素对象,文档层次结构中的元素节点。
Attr 属性,元素节点上的属性值节点。
Comment 注释对象,源文档中注释的表示形式。
Text 文本对象,包含文档中文本内容的节点

对XML文档的所有的操作都是基于DOM对象的操作

假如现在有一个xml文档,文档内容如下所示:


<Library libraryname="市中心图书馆">
    <staff explanation="员工">
        <people gender="" name="小明"/>
        <people gender="" name="小花"/>
    staff>
    
    <bookShelf name="人文类书架">
        <book isbn="****" date="2022-10-1">莎士比亚文集book>
        <book isbn="****" date="2022-10-2">童话故事book>
    bookShelf>
    <bookShelf name="自然类书架">
        <book isbn="****" date="2022-10-1">python程序设计book>
        <book isbn="****" date="2022-10-2">C++程序设计book>
    bookShelf>
Library>

整个文档为Document
,甚至元素的属性都是Node,多个Node组成Node List
但是,更确切的说,,Element,继承自Node。
Comment,也继承自Node。
其中的“莎士比亚文集”属于Text

1. Document

如果你想解析一篇xml文档,那么获取Document是解析的第一步。document包括从根到叶的所有内容
解析文档获取document对象:

from xml.dom.minidom import parse # 这个用来解析xml文档
# from xml.dom.minidom import parseString # 这个用来解析xml字符串
doc = parse("./test.xml")

document的方法和属性如下:

属性/方法 参数 返回值 解释
documentElement / Element 返回根节点,根节点只能有一个
getElementsByTagName() str NodeList 搜索所有的子节点
createElement() str Element 创建新元素节点
createTextNode() str Text 创建文本节点
createComment() str Comment 创建注释节点
createAttribute() str Attr 创建属性节点

2. Node

很多对象都是继承自Node,下面是一些Node的方法或者属性

属性/方法 参数 返回值 解释
nodeType / int 返回节点的类型
nodeName / str 获取节点名称,一般用于获取element名称
nodeValue / str 获取节点值,一般用于获取注释值
childNodes / NodeList 返回所有类型的节点
firstChild / Node 得到第一个节点
lastChild / Node 得到最后一个节点
hasAttributes() / bool 判断是否有属性
hasChildNodes() / bool 判断是否有子节点
appendChild() Node Node 添加节点
removeChild() Node Node 删除节点
replaceChild() Node,Node Node 替换节点

3. NodeList

使用getElementsByTagName()函数通常返回的是Node列表,

属性/方法 参数 返回值 解释
length / int 返回包含Node的数量
item() int Node 返回第i个Node

4. Element

Element对象时我们操作最频繁的对象,我们查找元素内容时,往往都是通过getElementsByTagName()来获取元素,再通过Element的一些方法来获取内容。

属性/方法 参数 返回值 解释
tagName / str 元素的名称
attributes / NodeMap 返回多个属性对象,类型是字典,遍历的时候要注意
getElementsByTagName() str ElementList 从名字获取元素
hasAttribute() str bool 判断是否有这个属性
getAttribute() str str 获取属性的值
getAttributeNode() str Attr 返回属性节点
removeAttribute() str 删除属性
setAttribute() str(属性名),str(属性值) 设置属性

5. Attr

属性 返回值 解释
name str 属性名称
value str 属性值

解析xml文档

对已有的xml文档处理,无非是查找信息、增添内容、删除内容、更改内容的操作。

1.查找内容

from xml.dom import minidom
from xml.dom.minidom import parse
doc=parse("./test.xml")

1.1 获取根元素:

root=doc.documentElement

# 获取根元素名称
root.tagName  # 或者: root.nodeName

# 获取根元素类型
root.nodeName # 输出的是元素类型

1.2 查找子元素:

查找子元素是主要针对元素来讲的,下面的element指的是xml文档中的Element对象

# 获取元素下面的所有子元素数量
element.childNodes.length

# 遍历元素下面的所有子元素
for child_node in element.childNodes:
    print("节点类型",child_node.nodeType)
    print("节点名称",child_node.nodeName)
    
# 获取元素下的位置为i的子节点(注意这是“节点”,不是“元素”;节点包括注释)
child_node =element.childNodes.item(i)

# 根据元素名查找
elements=root.getElementsByTagName("bookShelf")
# 遍历
for element in elements:
    print("元素名称:",element.tagName)
# 从ElementList找位置为i的元素
print("i处位置的元素:",elements[i]) # 或者elements.item(i)

1.3 获取元素的属性:

# 获取元素的所有属性对象
element.attributes # 返回的对象可以像字典一样遍历,想获取属性的名称和值需要遍历

# 遍历元素下的所有属性的名称和值
for key,value in element.attributes.items(): # 像字典一样遍历
    print("属性名:",key)
    print("属性值:",value)

# 获取特定属性
element.getAttribute("attr_name") 

1.4 获取文本

如果想获取book元素中的“莎士比亚文集”文本内容,需要通过Text对象操作。

<book isbn="****" date="2022-10-1">莎士比亚文集book>

Text对象本质上还是Node对象,可以使用firstChild()来获得。

elements=root.getElementsByTagName("book")
for element in elements:
    print("元素里的文本内容:",element.firstChild.data) # 或者是element.firstChild.nodeValue
    break # 只显示第一个book元素中的文本

2. 增加内容

创建内容需要使用document的create***()方法创建。然后将创建好的子节点使用元素的append()添加进去。
元素添加属性,需要使用setAttribute()
以下是向第一个bookshelf添加一本book元素的例子

doc=parse("./test.xml")
bookShelf1=doc.getElementsByTagName("bookShelf")[0]
new_book=doc.createElement("book")
new_book.setAttribute("isbn","******")
new_book.setAttribute("date","2022-10-3")
new_book.appendChild(doc.createTextNode("鲁迅全集"))
bookShelf1.appendChild(new_book)

最后需要将编辑的结果保存在文档中:

with open("test.xml", "w", encoding="utf-8") as f:
    doc.writexml(f, indent='', addindent='\t', newl='\n', encoding="utf-8")

添加注释同理

3. 删除内容

删除节点需要使用节点对象的removeChild();删除属性需要使用元素对象的removeAttribute()。
以下是删除刚添加的《鲁迅文集》这本书

bookShelf1=doc.getElementsByTagName("bookShelf")[0]
book_delete=bookShelf1.getElementsByTagName("book").item(2) # 把刚才的鲁迅文集这本书删除
bookShelf1.removeChild(book_delete)

删除之后别忘了保存到文件

4. 更新属性

更新节点可以使用节点对象的replace()方法;更改属性还是使用setAttribute()


创建xml文档

前面所述都是在已有xml文档的情况下操作。但是想新建一个新的xml文档怎么办?需要使用DOMImplementation来创建一个新document,然后使用writexml()保存就可以

例子:

from xml.dom.minidom import getDOMImplementation

impl = getDOMImplementation()

doc_new = impl.createDocument(None, "top", None)
root = doc_new.documentElement
text = doc_new.createTextNode('内容')
root.appendChild(text)
# 保存
with open("new.xml", "w", encoding="utf-8") as f:
    doc_new.writexml(f, indent='', addindent='\t', newl='\n', encoding="utf-8")

最后生成的结果如下:

<?xml version="1.0" encoding="utf-8"?>
<top>内容</top>

你可能感兴趣的:(python,xml,python)