在Selenium自动化测试的实际工作中,除了处理HTML页面元素,很多时候还需要对接口返回的xml格式数据或者本地xml配置文件进行内容定位,XPath作为一门在XML文档中查找信息的语言,能够很好地满足这类定位需求。

XPath定位xml的核心基础
XPath通过路径表达式来选取xml文档中的节点或节点集,xml文档的节点类型和HTML类似,包含元素节点、属性节点、文本节点等,理解节点关系是使用XPath的前提。
比如下面是一份简单的xml示例文档,后续我们会基于这份文档演示XPath的使用:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="编程">
<title lang="zh">Selenium实战指南</title>
<author>张三</author>
<price>59.9</price>
</book>
<book category="测试">
<title lang="en">Automation Testing</title>
<author>李四</author>
<price>49.9</price>
</book>
</bookstore>
常用XPath语法在xml定位中的应用
1. 节点选择语法
基础的路径表达式可以直接选取对应节点:
nodename:选取此节点的所有子节点/:从根节点开始选取//:从匹配选择的当前节点选择文档中的节点,不考虑位置.:选取当前节点..:选取当前节点的父节点@:选取属性
比如要选取所有book节点,可以使用//book表达式;要选取根节点bookstore下的所有book节点,可以使用/bookstore/book表达式。
2. 谓语筛选语法
谓语用来查找某个特定的节点或者包含某个指定值的节点,谓语被嵌在方括号中:
- 选取第一个book节点:
/bookstore/book[1] - 选取最后一个book节点:
/bookstore/book[last()] - 选取price大于50的book节点:
/bookstore/book[price>50] - 选取category属性为编程的book节点:
/bookstore/book[@category="编程"]
3. 通配符与多路径选择
XPath支持通配符匹配和多个路径同时选取:
*:匹配任何元素节点,比如/bookstore/*会选取bookstore下的所有子元素节点@*:匹配任何属性节点,比如//title[@*]会选取所有带属性的title节点|:选取多个路径,比如//title|//price会同时选取所有title和price节点
Selenium中结合XPath定位xml的实现
在Selenium中处理xml内容时,通常需要先将xml数据转换为可解析的对象,再结合XPath进行查找,以下是使用Python语言结合Selenium相关库的完整示例:
import xml.etree.ElementTree as ET
from selenium import webdriver
# 解析本地xml文件
tree = ET.parse('test.xml')
root = tree.getroot()
# 使用XPath查找所有category为编程的book的title文本
# ElementTree的findall方法支持部分XPath语法
programming_books = root.findall(".//book[@category='编程']/title")
for book in programming_books:
print("编程类书籍名称:", book.text)
# 如果是接口返回的xml字符串,可以先解析字符串
xml_str = """<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="编程">
<title lang="zh">Selenium实战指南</title>
<author>张三</author>
<price>59.9</price>
</book>
</bookstore>"""
root_str = ET.fromstring(xml_str)
# 查找所有title的lang属性
titles = root_str.findall(".//title")
for title in titles:
lang_attr = title.get("lang")
print("title的lang属性值:", lang_attr)
# 若需要在浏览器环境中处理页面内嵌的xml数据,可通过Selenium获取元素文本后解析
driver = webdriver.Chrome()
driver.get("http://ipipp.com/xml_page")
# 假设页面有id为xmlContent的元素包含xml内容
xml_content = driver.find_element("id", "xmlContent").text
root_page = ET.fromstring(xml_content)
# 查找所有price节点
prices = root_page.findall(".//price")
for price in prices:
print("书籍价格:", price.text)
driver.quit()
注意事项
需要注意Selenium自带的XPath定位主要是针对HTML DOM的,处理独立xml文档时更推荐使用Python的xml.etree.ElementTree或者lxml库,这些库的XPath支持更完整。另外编写XPath表达式时要注意xml的命名空间问题,如果xml文档带有命名空间,需要在表达式中做对应的处理,避免定位失败。同时测试过程中可以先使用xml在线解析工具验证XPath表达式的正确性,再写入测试脚本中,减少调试成本。