说明
- xml是程序运行常用的文本形式,此处示例应用的是ABB机器人webservice request后的 xml文本解析;
- 你需要了解xml文档的基本语法及数据结构,xml的根,子节点,标签,属性,文本及尾
- xml文本解析主要有两个方面的不同,一种是带命名空间的,一种是不带命名空间,用法上如果带有命名空间则在解析时需要在标签前添加上相应的命名空间否则找不到结果。名称空间一般在根节点的属性中,格式为xmlns=<str>
- 解析xml文件需要用到xml文件解析模块xml.etre.ElementTree
- 获取数据时同样需要用到xpath语法用于根节点的findall方法查找节点
导入模块
import xml.etree.ElementTree as ET
import re
xml文本
如果想显示正确的xml文本格式,可以使用在线的xml文本编辑器,菜鸟教程xml在线编辑器
# 带有命名空间的xml文本
str_xml = """<?xml version="1.0" encoding="utf-8"?>
<html
xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Event</title>
<base href="http://127.0.0.1:80/"/>
</head>
<body>
<div class="state">
<a href="subscription/53" rel="group"></a>
<ul>
<li class="ios-signalstate-ev" title="do_ws_signal">
<a href="/rw/iosystem/signals/do_ws_signal;state" rel="self"/>
<span class="lvalue">1</span>
<span class="lstate">not simulated</span>
</li>
</ul>
</div>
</body>
</html>
"""
# 不带有命名空间的xml文本
str_xml_without_space = """<?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>"""
详细代码示例
# 解析不带有命名空间的文本
root1 = ET.fromstring(str_xml_without_space)
print(root1)
print(root1.findall('./country')[0].attrib)
# 解析带有命名空间的文本
root_space = ET.fromstring(str_xml)
print(root_space.tag)
# 检查xml文本中是否带有命名空间
xml_space = re.findall(r"{\S+}", root_space.tag)[0]
if xml_space:
print('xml space:' + xml_space)
else:
xml_space = ''
print("Doesn't find name space in the str")
# 在有命名空间的文件中如果不添加命名空间将找不到相应的结果
# print(root_space.findall('.')[0].attrib)
# print(root_space.findall("./"))
# print(root_space.findall("."))
# print('root text: ' + root_space.findtext('./'))
root_li = root_space.findall(".//{0}li".format(xml_space))
for _index in root_li:
print('tag: ' + _index.tag)
print('attrib: ' + str(_index.attrib['title']))
if _index.findall('./{0}a'.format(xml_space)):
print(_index.findall('./{0}a'.format(xml_space))[0].attrib['href'].split(';')[0])
if _index.findall('./{0}span'.format(xml_space)):
print(_index.findall('./{0}span'.format(xml_space))[0].text)
print(_index.findall('./{0}span'.format(xml_space))[1].text)
print(root_space.findall("./{0}body".format(xml_space)))
技术细节
示例解析xml文本主要用到了xml模块,及正则表达式模块re用于匹配xml文件是否使用了命名空间,如果使用则将命名空间提取出来供后面使用;
在解析xml文件是需要了解xml的语法格式,标签,属性,内容及尾,还有xpath的语法来正确的提取到相应的文本信息
xpath语法可以在官方的xml文档中找到详细说明,参考地址xml官方文档说明
小结
此处xml文档解析主要通过示例来了解xml模块的用法及简单示例,如果想更深入的了解相关信息,请查看官方文档