10分钟掌握Python xml.dom

前言

文章的目的是使读者快速掌握Python xml.dom的基本功能,10分钟学会使用xml.dom完成xml的读写。

文章中包含大量的代码示例,可以直接引用到工作项目中,提升开发效率。

Python xml.dom是什么?

xml是Python标准库的一员,专门处理xml文件的数据处理。xml库中包含了许多处理xml文件数据的子库,xml.dom就是其中一个。

既然使标准库的一部分,就不需要额外安装了。

xml文件的结构

既然是处理xml文件的,那么我们还是先来看看标准的xml文件是什么样子的。

<?xml version="1.0" encoding="utf-8"?>
<bookstore>
    <book category="COOKING">
        <title lang="en">Everyday Italian</title>
        <author>Giada De Laurentiis</author>
        <year>2005</year>
        <price>30.00</price>
    </book>
    <book category="CHILDREN">
        <title lang="en">Harry Potter</title>
        <author>J K. Rowling</author>
        <year>2005</year>
        <price>29.99</price>
    </book>
    <book category="WEB">
        <title lang="en">Learning XML</title>
        <author>Erik T. Ray</author>
        <year>2003</year>
        <price>39.95</price>
    </book>
</bookstore>

上面是一个典型的xml文件的结构,例子来源于:

XML 树结构 (w3school.com.cn)

 xml文档是一种树状结构,有唯一的根(root)和无数的枝叶。

上面例子中<boostore>就是根,<book>是根下的第一层叶子,<title>、<author>、<year>和<price>是<book>下的叶子。

叶子上面可以有值,例如<year>的值就是2003等等,叶子上还可以有属性,例如<title>有一个叫lang的属性。

xml.dom的对象

好了,上面我们大致了解了一个xml文档的结构。下面我们来看看xml.dom提供哪些组件(对象)来处理xml的各个元素。

  • Document
  • Element
  • Attr
  • Text
  • Node

Document

这个对象包含xml文件的全部内容,从根开始,到所有的枝叶,都包含在document对象中。

一般在读取xml文件的时候,我们首先要拿到的就是这个对象。

Element

每一对<></>包含的内容都是一个Element,例如<book></book>。

其中的book叫tagName,所以当我们拿到Document对象后,可用通过getElementsByTagName(tagName)来找到所有叫tagName的Element,不仅是第一层的Element,而是所有。

Attr

<book category="COOKING"></book>中的category就是Attr。

可用通过Element对象的getAttribute(name)获得特定Attr的值。

Text

<author>Giada De Laurentiis</author>中的“Giada De Laurentiis”就是Text对象,可以通过author这个Element对象firstChild()方法获得。

注意firstChild()方法不是Element类的方法,是其父类Node的方法。

Node

Document、Element和Attr都是Node子类,因此他们都是Node。

Node提供了一些基础方法和属性,感兴趣的话可以查阅下面的参考资料。

读取xml

# 首先引入xml.dom.minidom库的xml解析器
from xml.dom.minidom import parse

# 使用解析器解析example.xml文件,dom是返回的document对象
dom = parse('example.xml')
# 获取xml中所有叫book的Element
# 注意books是NodeList对象,可以通过NodeList对象的item(i)方法获取具体的Node,
# 也可以通过NodeList对象的length属性得到Node数量
books = dom.getElementsByTagName('book')
print(len(books))

# 循环遍历每一个叫book的Element
# 打印其子Element的信息
for book in books:
    print(book.tagName)
    print(book.getAttribute('category'))
    titles = book.getElementsByTagName('title')
    authors = book.getElementsByTagName('author')
    years = book.getElementsByTagName('year')
    prices = book.getElementsByTagName('price')
    print(titles.item(0).firstChild.data)
    print(authors.item(0).firstChild.data)
    print(years.item(0).firstChild.data)
    print(prices.item(0).firstChild.data)

在上面的例子中,我们首先引入了一个xml.dom.minidom的xml解析器parse,然后利用parse解析了xml文件example.xml。

example.xml的内容就是文章开始举得xml文件结构的例子。

parse返回一个Document对象,叫dom。然后我们通过Document对象的getElementsByTagName()方法获取到了所有叫book的Element对象,并把每个book的内容打印出来。其中,我们通过Element对象的tagName属性获得了Element的名称;通过getAttibute()方法获得了属性的值;然后通过item()拿到了book内各个Element内的Node,最后通过Node对象的data属性拿到了其文字内容,例如“2005”。

创建xml

# 引入xml.dom模块
import xml.dom

# 获得DOMImplementation对象
domImp = xml.dom.getDOMImplementation()

# 通过DOMImplementation对象创建Document对象
doc = domImp.createDocument(None, None, None)

# 为Document对象添加root节点
rootNode = doc.createElement("person_table")
doc.appendChild(rootNode)

# 为root节点创建一个person子节点:小明
xiaomingNode = doc.createElement("person")
rootNode.appendChild(xiaomingNode)

## 为xiaomingNode添加name属性
nameNode = doc.createAttribute("name")
xiaomingNode.setAttributeNode(nameNode)
xiaomingNode.setAttribute("name","小明")

## 为xiaomingNode添加电话节点
telNode = doc.createElement("tel")
telValue = doc.createTextNode("15942637104")
telNode.appendChild(telValue)
xiaomingNode.appendChild(telNode)

# 为rootNode添加另一个person子节点
xiaohongNode = doc.createElement("person")
rootNode.appendChild(xiaohongNode)

## 添加name属性
nameNode = doc.createAttribute("name")
xiaohongNode.setAttributeNode(nameNode)
xiaohongNode.setAttribute("name","小红")

## 为xiaohongNode添加电话节点
telNode = doc.createElement("tel")
telValue = doc.createTextNode("15330838240")
telNode.appendChild(telValue)
xiaohongNode.appendChild(telNode)

print(doc.toxml())

with open("new.xml", 'w', encoding='utf-8') as writer:
    doc.writexml(writer, indent='\n', addindent='    ')

上面的例子完整地从无到有创建了一个具有简单内容的xml文件。

我们来看看它是如何创建的:

  1. 引入xml.dom模块
  2. 通过xml.dom模块获得dom接口对象:domImp
  3. 通过dom接口对象domImp获得Document对象,此时我们终于有了可以操作的xml内存对象,只不过它是一个只具备“<?xml version="1.0" ?>”的空xml
  4. 通过document对象的createElement()方法创建root节点(person_table),并添加到document对象上,后续所有种类的节点(node)都可以通过document对象的不同方法创建
  5. 为root节点创建两个person子节点,其name属性分别是“小名”和“小红”
  6. 为“小明”和“小红”添加tel子节点,注意tel节点的内容也是节点,tel的类型是Element,而其内容的类型是Text
  7. 通过node的toxml()方法把内存中的xml数据转换成string,再通过print()方法输出到console上
  8. 最后通过node的writexml()方法生成xml文件落盘,文件的名字叫“new.xml”,注意indent参数表示每个标签后跟随的字符,addindent表示换行后子节点相对父节点的缩进距离,例子中是4个空格

 生成的new.xml如下:

<?xml version="1.0" ?>
<person_table>
    <person name="小明">
        <tel>15942637104</tel>
    </person>
    <person name="小红">
        <tel>15330838240</tel>
    </person>
</person_table>

总结

  1. 我们了解了xml文件的基本结构以及每一种元素对应的xml.dom中的处理对象
  2. 我们通过两个例子了解了基本的xml文件读取和写入
  3. xml.dom中有一个特别的对象:Node,其他所有对象都继承于Node,Node对象提供很多基础的、共通的方法帮助我们获取节点的信息,添加或删除节点等,以便我们能够更加智能的处理xml文件,详细内容可以参见下面的参考资料

参考资料

xml.dom — The Document Object Model API — Python 3.9.5 documentation

xml.dom.minidom — Minimal DOM implementation — Python 3.9.5 documentation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值