首页
学习
活动
专区
圈层
工具
发布
28 篇文章
1
一篇文章让你入门API测试
2
[接口测试 - 基础篇] 01 你应该了解的协议基础
3
[接口测试 - 基础篇] 02 你应该掌握的Python3接口测试内功
4
[接口测试 - 基础篇] 03 unittest测试框架了解多少才够?
5
[接口测试 - 基础篇] 04 无法绕过的json解析
6
[接口测试 - 基础篇] 05 好讨厌的xml解析
7
[接口测试 - 基础篇] 06 好吧也来解析下html
8
[接口测试 - 基础篇] 07 来来来,一起读写excel玩玩之一
9
[接口测试 - 基础篇] 08 封装个基本的excel解析类
10
[接口测试 - 基础篇] 09 其实吧,读写csv格式也是要掌握的
11
[接口测试 - 基础篇] 10 别啊,还有INI格式呢,别忘记我
12
[接口测试 - 基础篇] 11 掌握下python解析YAML格式也是需要的
13
[接口测试 - 基础篇] 12 还是要掌握python日志管理模块的
14
[接口测试 - 基础篇] 13 写在接口测试基础篇完结时
15
[接口测试 - http.client篇] 14 源码初探及其工作机制分析
16
[接口测试 - http.client篇] 15 常用API说明及基本的示例
17
[接口测试 - http.client篇] 16 基于http.client之POM实战一下
18
[接口测试 - http.client篇] 17 http.client之入门级接口测试框架
19
接口测试 | urllib篇 18 urllib介绍
20
接口测试 | urllib篇 19 urllib基本示例
21
[接口测试 -基础篇] 20 用flask写一个简单server用于接口测试
22
接口测试 | 21 基于flask弄个restful API服务出来
23
接口测试 | 22 requests基础入门
24
接口测试 23 requests基础入门二
25
接口测试 | 24 requests + unittest集成你的接口测试
26
接口测试 | 25 requests + pytest测试实例
27
接口测试 | 26 基础及简要验证清单
28
接口测试 | 27 HTTP接口详细验证清单

[接口测试 - 基础篇] 05 好讨厌的xml解析

概述

什么是XML?

XML 指可扩展标记语言(eXtensible Markup Language)。 XML 被设计用来传输和存储数据。

XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识。

它也是元标记语言,即定义了用于定义其他与特定领域有关的、语义的、结构化的标记语言的句法语言。

xml构成

XML由3个部分构成,它们分别是:

  • 文档类型定义(Document Type Definition,DTD),即XML的布局语言
  • 可扩展的样式语言(Extensible Style Language,XSL),即XML的样式表语言
  • 可扩展链接语言(Extensible Link Language,XLL)

Python解析xml的方法

常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同,当然使用场合也不同。

python有三种方法解析XML,SAX,DOM,以及ElementTree:

  1. SAX (simple API for XML ) python 标准库包含SAX解析器,SAX用事件驱动模型,通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。
  2. DOM(Document Object Model) 将XML数据在内存中解析成一个树,通过对树的操作来操作XML。
  3. ElementTree(元素树) ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。

本文只介绍ElementTree方式解析xml。

一个基本xml片段

下面我们尝试解析下面这一段xml:

代码语言:javascript
复制
<?xml version="1.0"?><data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country></data>

或是将上面这段xml内容保存至xml_data.xml中。

代码示例

下面通过一段完整的代码演示如何读取、修改和保存xml。

代码语言:javascript
复制
#-*- coding:utf-8 -*-__author__ = "苦叶子"# 导入ElementTreeimport xml.etree.ElementTree as ETif __name__ == "__main__":
    print("python xml解析实例")

    data = """<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
    """
    # 载入xml的两种方式,一种从文件,一种从xml字符串
    # 注意区别:从xml字符串加载的xml直接返回root元素对象
    # 而从文件加载xml返回是xml树

    # 大家根据实际情况来决定用哪种方式即可
    # 本示例从xml字符串载入进行演示

    # 从文件加载xml,获取xml tree节点
    # tree = ET.parse('xml_data.xml')
    
    # 获取根节点
    # root = tree.getroot()

    # 从字符串加载xml
    root = ET.fromstring(data)    # 打印下根节点的节点tag, 输出data
    print(root.tag)    # 遍历下根节点的所有子节点及其属性
    print("---" * 10)    for child in root:
        print(child.tag, " ", child.attrib)    
    # 找所有的year节点玩下
    print("---" * 10)    for child in root.iter("year"):        # 打印出year节点的tag和text
        print(child.tag, " ", child.text)    
    # 修改下节点的text试试, 把year节点所有2011修改为2017
    print("---" * 10)    for child in root.iter("year"):        if child.text == "2011":
            child.text = "2017"
            child.set('updated', 'yes')    
    # 打印下修改后的xml所有的year节点
    print("将2011 -> 2017")    for child in root.iter("year"):        # 打印出year节点的tag和text
        print(child.tag, " ", child.text)    
    # 给每个country节点新增一个<wx>开源优测</wx>的节点试试
    print("---" * 10)    for child in root.iter("country"):
        wx = ET.SubElement(child, "wx")
        wx.text = "开源优测"
    
    # 遍历wx节点,并打印
    for child in root.iter("wx"):
        print(child.tag, " ", child.text)    
    # 下面演示删除所有的neighbor节点
    # 当然你自己可以加判断条件删除指定的节点,自行尝试吧
    print("---" * 10)    for child in root.findall("neighbor"):
        root.remove(child)    
    # 保存上述操作后的xml至xml_write_data.xml
    xml_update_data = ET.tostring(root, encoding="unicode")    # 写入xml_write_data.xml
    import codecs  
    fp = codecs.open("xml_write_data.xml","w","utf-8") 
    
    fp.write(xml_update_data)
    
    fp.close()

经过上述一系列代码操作后保存至xml_write_data.xml中的xml内容如下:

代码语言:javascript
复制
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    <wx>开源优测</wx></country>
    <country name="Singapore">
        <rank>4</rank>
        <year updated="yes">2017</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    <wx>开源优测</wx></country>
    <country name="Panama">
        <rank>68</rank>
        <year updated="yes">2017</year>
        <gdppc>13600</gdppc>
        <neighbor direction="W" name="Costa Rica" />
        <neighbor direction="E" name="Colombia" />
    <wx>开源优测</wx></country></data>

小结

本文所述仅仅是ElementTree的极小部分功能,更多的功能请参见官方文档学习。

下一篇
举报
领券