Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Python 关于xpath查找XML元素的一点总结

Python 关于xpath查找XML元素的一点总结

作者头像
授客
发布于 2019-09-11 08:41:37
发布于 2019-09-11 08:41:37
2K0
举报
文章被收录于专栏:授客的专栏授客的专栏

测试环境

Win7 64

python 3.4.0

实践出真知

代码如下,更换不同的xpath,和response_to_check进行测试

实验1

xpath = ".//xmlns:return//xmlns:copeWith"

response_to_check = '' \ '<soap:Envelope xmlns="http://www.examp.com" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" >' \ ' <node2>' \ ' <id>goods1</id>' \ ' </node2> ' \ ' <ns1:Body xmlns:ns1="http://service.rpt.data.platform.ddt.sf.com/">' \ ' <ns2:selectByPrimaryKeyResponse xmlns:ns2="http://service.rpt.data.platform.ddt.sf2.com/" ' \ ' xmlns="http://www.overide_first_defaul_xmlns.com"> ' \ ' <return>' \ ' <copeWith>1.00</copeWith>' \ ' <discount>0.99</discount>' \ ' <id>144</id>' \ ' <invoice>2</invoice>' \ ' <invoiceType></invoiceType>' \ ' <orderCode>DDT201704071952057186</orderCode>' \ ' <orderDate>2017-04-07 19:52:06.0</orderDate>' \ ' <paid>0.01</paid>' \ ' <payType>pc</payType>' \ ' <productName>快递包</productName>' \ ' <state>0</state>' \ ' <userId>2</userId>' \ ' </return>' \ ' <return>' \ ' <copeWith>2.00</copeWith>' \ ' <discount>0.99</discount>' \ ' <id>143</id>' \ ' <invoice>2</invoice>' \ ' <invoiceType></invoiceType>' \ ' <orderCode>DDT201704071951065731</orderCode>' \ ' <orderDate>2017-04-07 19:51:07.0</orderDate> ' \ ' <paid>0.01</paid>' \ ' <payType>pc</payType>' \ ' <productName>快递包</productName>' \ ' <state>0</state>' \ ' <userId>2</userId>' \ ' </return>' \ ' <return>' \ ' <copeWith>3.00</copeWith>' \ ' <discount>0.99</discount>' \ ' <id>142</id>' \ ' <invoice>2</invoice>' \ ' <invoiceType></invoiceType>' \ ' <orderCode>DDT201704071945408575</orderCode>' \ ' <orderDate>2017-04-07 19:45:40.0</orderDate>' \ ' <paid>0.01</paid>' \ ' <payType>pc</payType>' \ ' <productName>快递包</productName>' \ ' <state>0</state>' \ ' <userId>2</userId>' \ ' </return> ' \ ' <return attr="re">' \ ' <copeWith>4.00</copeWith>' \ ' <copeWith>5.00</copeWith>' \ ' <discount>0.99</discount>' \ ' <id>141</id>' \ ' <invoice>1</invoice>' \ ' <invoiceType>增值税普通发票</invoiceType>' \ ' <orderCode>DDT201704071845403738</orderCode>' \ ' <orderDate>2017-04-07 18:45:41.0</orderDate>' \ ' <paid>0.01</paid>' \ ' <productName>快递包</productName>' \ ' <state>0</state>' \ ' <userId attr="testattr">2</userId>' \ ' </return>' \ ' </ns2:selectByPrimaryKeyResponse>' \ ' </ns1:Body>' \ ' <ns1:Body xmlns:ns1="http://service.rpt.data.platform.ddt.sf.com/">' \ ' <ns2:selectByPrimaryKeyResponse xmlns:ns2="http://service.rpt.data.platform.ddt.sf2.com/"> ' \ ' </ns2:selectByPrimaryKeyResponse>' \ ' <ns2:selectByPrimaryKeyResponse xmlns:ns2="http://service.rpt.data.platform.ddt.sf2.com/"> ' \ ' </ns2:selectByPrimaryKeyResponse>' \ ' </ns1:Body>' \ '</soap:Envelope>'

root = ET.fromstring(response_to_check) print(root) if xpath == '.': text_of_element = root.text else: xmlnsnamespace_dic = {} # 存放名称空间定义 print('正在获取xmlns定义') match_result_list =re.findall('xmlns[^:]?=(.+?)[ |\>|\\\>]', response_to_check, re.MULTILINE) if match_result_list: xmlns = match_result_list[len(match_result_list) - 1] xmlns = xmlns.strip(' ') xmlns = '{' + xmlns + '}' print('xmlns定义为:%s' % xmlns) xmlnsnamespace_dic['xmlns'] = xmlns print('正在获取"xmlns:xxx名称空间定义') match_result_list = re.findall('xmlns:(.+?)=(.+?)[ |>]', response_to_check) for ns in match_result_list: xmlnsnamespace_dic[ns[0]] = '{' + ns[1] + '}' print("最后获取的prefix:uri为:%s" % xmlnsnamespace_dic) print('正在转换元素结点前缀') for dic_key in xmlnsnamespace_dic.keys(): namespace = dic_key + ':' if namespace in xpath: uri = xmlnsnamespace_dic[dic_key] xpath = xpath.replace(namespace, uri) xpath = xpath.replace('"','') print('转换后用于查找元素的xpath:%s' % xpath) try: elements_list = root.findall(xpath) except Exception as e: print('查找元素出错:%s' % e) print('查找到的元素为:%s' % elements_list) for element in elements_list: text_of_element = element.text print(text_of_element)

实验结果

以下为xpath设置不同值时的查找结果

/node 查找结果:报错,不能使用绝对路径

./node2 查找结果:找不到元素

./Body 查找结果:找不到元素

./ns1:Body/selectByPrimaryKeyResponse 查找结果:找不到元素

./ns1:Body/ns2:selectByPrimaryKeyResponse/return

查找结果:找不到元素

./ns1:Body/ns2:selectByPrimaryKeyResponse/xmlns:return[1]/copeWith 查找结果:找不到元素

----------------------------- .

查找结果:根元素,即Envelope元素

ns1:Body 查找结果:所有名称空间为ns1的Body元素

./ns1:Body 查找结果:等同ns1:Body

./ns1:Body/ns2:selectByPrimaryKeyResponse

查找结果:所有名称空间为ns1的Body元素下的所有名为selectByPrimaryKeyResponse的子元素

./ns1:Body/ns2:selectByPrimaryKeyResponse[2] 查找结果:所有名称空间为ns1的Body元素下,名称空间为ns2的第2个名为selectByPrimaryKeyResponse的子元素

./ns1:Body/ns2:selectByPrimaryKeyResponse/xmlns:return 查找结果:所有名称空间为ns1的Body元素下,所有名称空间为ns2,名称为selectByPrimaryKeyResponse的子元素下,所有名称空间定义为 http://www.overide_first_defaul_xmlns.com的return元素

./ns1:Body/ns2:selectByPrimaryKeyResponse/xmlns:return[1]/xmlns:copeWith

查找结果:所有名称空间为ns1的Body元素下,所有名称空间为ns2,名称为selectByPrimaryKeyResponse的子元素下,第一个名称空间定义为http://www.overide_first_defaul_xmlns.com的return元素下,

名称空间定义为http://www.overide_first_defaul_xmlns.com的copyWith元素

.//xmlns:copeWith 查找结果:所有名称空间定义为http://www.overide_first_defaul_xmlns.com的copeWith元素

.//xmlns:copeWith[2] 查找结果:同一个元素节点下,名称空间定义为http://www.overide_first_defaul_xmlns.com的第二个copeWith元素(例中为 <copeWith>5.00</copeWith>' ,注意:这里的数字是针对兄弟节点的,下同,不再赘述)

# 注意:[]里面不支持last()这种谓词,数字可以

.//xmlns:return//xmlns:copeWith" 查找结果:所有名称空间定义为http://www.overide_first_defaul_xmlns.com的return元素下,所有名称空间定义为http://www.overide_first_defaul_xmlns.com的copeWith元素

实验2

对比实验1,去掉selectByPrimaryKeyResponse元素中的xmlns定义:

xmlns="http://www.overide_first_defaul_xmlns.com"

xpath = ".//xmlns:return//xmlns:copeWith" response_to_check = '' \ '<soap:Envelope xmlns="http://www.examp.com" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" >' \ ' <node2>' \ ' <id>goods1</id>' \ ' </node2> ' \ ' <ns1:Body xmlns:ns1="http://service.rpt.data.platform.ddt.sf.com/">' \ ' <ns2:selectByPrimaryKeyResponse xmlns:ns2="http://service.rpt.data.platform.ddt.sf2.com/" ' \ ' > ' \ ' <return>' \ ' <copeWith>1.00</copeWith>' \ ' <discount>0.99</discount>' \ ' <id>144</id>' \ ' <invoice>2</invoice>' \ ' <invoiceType></invoiceType>' \ ' <orderCode>DDT201704071952057186</orderCode>' \ ' <orderDate>2017-04-07 19:52:06.0</orderDate>' \ ' <paid>0.01</paid>' \ ' <payType>pc</payType>' \ ' <productName>快递包</productName>' \ ' <state>0</state>' \ ' <userId>2</userId>' \ ' </return>' \ ' <return>' \ ' <copeWith>2.00</copeWith>' \ ' <discount>0.99</discount>' \ ' <id>143</id>' \ ' <invoice>2</invoice>' \ ' <invoiceType></invoiceType>' \ ' <orderCode>DDT201704071951065731</orderCode>' \ ' <orderDate>2017-04-07 19:51:07.0</orderDate> ' \ ' <paid>0.01</paid>' \ ' <payType>pc</payType>' \ ' <productName>快递包</productName>' \ ' <state>0</state>' \ ' <userId>2</userId>' \ ' </return>' \ ' <return>' \ ' <copeWith>3.00</copeWith>' \ ' <discount>0.99</discount>' \ ' <id>142</id>' \ ' <invoice>2</invoice>' \ ' <invoiceType></invoiceType>' \ ' <orderCode>DDT201704071945408575</orderCode>' \ ' <orderDate>2017-04-07 19:45:40.0</orderDate>' \ ' <paid>0.01</paid>' \ ' <payType>pc</payType>' \ ' <productName>快递包</productName>' \ ' <state>0</state>' \ ' <userId>2</userId>' \ ' </return> ' \ ' <return attr="re">' \ ' <copeWith>4.00</copeWith>' \ ' <copeWith>5.00</copeWith>' \ ' <discount>0.99</discount>' \ ' <id>141</id>' \ ' <invoice>1</invoice>' \ ' <invoiceType>增值税普通发票</invoiceType>' \ ' <orderCode>DDT201704071845403738</orderCode>' \ ' <orderDate>2017-04-07 18:45:41.0</orderDate>' \ ' <paid>0.01</paid>' \ ' <productName>快递包</productName>' \ ' <state>0</state>' \ ' <userId attr="testattr">2</userId>' \ ' </return>' \ ' </ns2:selectByPrimaryKeyResponse>' \ ' </ns1:Body>' \ ' <ns1:Body xmlns:ns1="http://service.rpt.data.platform.ddt.sf.com/">' \ ' <ns2:selectByPrimaryKeyResponse xmlns:ns2="http://service.rpt.data.platform.ddt.sf2.com/"> ' \ ' </ns2:selectByPrimaryKeyResponse>' \ ' <ns2:selectByPrimaryKeyResponse xmlns:ns2="http://service.rpt.data.platform.ddt.sf2.com/"> ' \ ' </ns2:selectByPrimaryKeyResponse>' \ ' </ns1:Body>' \ '</soap:Envelope>'

实验结果

.//xmlns:return//xmlns:copeWith 查找结果:所有名称空间定义为http://www.examp.com的return元素下,所有名称空间定义为http://www.examp.com的copeWith元素

实验3

xpath = "./xmlns:string" response_to_check =''\ '<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' \ ' xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://WebXml.com.cn/">' \ ' <string>阿尔及利亚,3320</string>' \ ' <string>阿根廷,3522</string>' \ ' <string>阿曼,3170</string>' \ ' <string>阿塞拜疆,3176</string>' \ ' <string>埃及,3317</string>' \ ' <string>埃塞俄比亚,3314</string>' \ ' <string>爱尔兰,3246</string>' \ ' <string>奥地利,3237</string>' \ ' <string>澳大利亚,368</string>' \ ' <string>巴基斯坦,3169</string>' \ ' <string>巴西,3580</string>' \ ' <string>保加利亚,3232</string>' \ ' <string>比利时,3243</string>' \ '</ArrayOfString>'

实验结果: ./string 查找结果:找不到元素

./xmlns:string 查找结果:根元素下,所有名称空间定义为 xmlns的string元素

实验4

对比实验3,去掉xmlns=xmlns="http://WebXml.com.cn/

xpath = "./string" response_to_check =''\ '<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' \ ' xmlns:xsd="http://www.w3.org/2001/XMLSchema">' \ ' <string>阿尔及利亚,3320</string>' \ ' <string>阿根廷,3522</string>' \ ' <string>阿曼,3170</string>' \ ' <string>阿塞拜疆,3176</string>' \ ' <string>埃及,3317</string>' \ ' <string>埃塞俄比亚,3314</string>' \ ' <string>爱尔兰,3246</string>' \ ' <string>奥地利,3237</string>' \ ' <string>澳大利亚,368</string>' \ ' <string>巴基斯坦,3169</string>' \ ' <string>巴西,3580</string>' \ ' <string>保加利亚,3232</string>' \ ' <string>比利时,3243</string>' \ '</ArrayOfString>'

实验结果: ./string

查找结果:根元素下,所有名称空间定义为 http://WebXml.com.cn/的string元素

总结

1)xmlns=URI定义元素默认的名称空间,使得作用范围内,可不用为元素显示设置名称空间前缀。

<element_node xmlns=URI>

<node1>

...

<node2>

</element_node>

xmlns=URI的作用域如下:

<element_node xmlns=URI>

作用域,也就是说,仅在元素范围内

</element>

2) 一份xml文档中,同时只能存在一个默认的xmlns名称空间,后续元素标签中定义的xmlns会自动导致前面定义的xmlns不可用

3)为元素设置自定义名称空间,形式如下:

<namespace:element_name xmlns:namespace=URI>

</namespace:element_name>

4)xpath查找,不能使用绝对路径。

5)根据实验1,实验1&实验2对比,实验3&实验4对比得出:

如果设置了xmlns(默认名称空间xmlns=xxxx,或者非默认的自定义名称空间xmlns:prefix=URI),那么xpath查找名称空间作用域内的子元素时,必须使用名称空间查找./xmlns:node_name、./prefix:node_name。

如果xmlns默认名称空间作用域范围内,子元素标签内设置了自定义名称空间,那么使用自定义名称空间查找 ./…/prefix:node_name

如果既没定义默认名称空间,也没设置自定义名称空间,那么xpath查找元素时可不用指定名称空间 ./node_name

采用网盘链接分享,请点击链接查看:

关于xpath查找XML元素的一点总结.pdf

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-02-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax
本文主要涉及:xml概念描述,xml的约束文件,dtd,xsd文件的定义使用,如何在xml中引用xsd文件,如何使用java解析xml,解析xml方式dom sax,dom4j解析xml文件
noteless
2018/09/11
3.3K0
XML概念定义以及如何定义xml文件编写约束条件java解析xml   DTD XML Schema JAXP java xml解析 dom4j  解析 xpath dom sax
SoapUI中是如何断言的呢(三)
Xquery匹配声明 它使用Xquery表达式从target属性中选择内容。为了更好地理解XQuery,我们需要更大的响应XML,让我们导入另一个WSDL,如下所示:http : //www.webs
用户7466307
2020/06/17
1.2K0
方法关键字SoapBindingStyle,SoapBodyUse,SoapMessageName,SoapNameSpace
指定此方法用作web方法时使用的绑定样式或SOAP调用机制。仅适用于定义为web服务或web客户端的类。
用户7741497
2022/07/07
5130
计算XPath表达式
XPath(XML路径语言)是一种基于XML的表达式语言,用于从XML文档获取数据。使用类中的%XML.XPATH.Document,可以轻松地计算XPath表达式(给定提供的任意XML文档)。
用户7741497
2022/07/05
1.7K0
WebService使用介绍(二)
SOAP即Simple Object Access Protocol简易对象访问协议
HUC思梦
2020/09/03
2.5K0
XPath知识点梳理
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.csdn.net/article/details/19197949
亦山
2019/05/25
1.2K0
day45_Webservice学习笔记_01
Web service 即web服务,它是一种跨编程语言和跨操作系统平台的远程调用技术即跨平台远程调用技术。
黑泽君
2018/10/11
1.5K0
day45_Webservice学习笔记_01
Python网络爬虫(四)- XPath1.XPath2.XPath在python中的应用
XPath 即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。它使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。 XPath语法
Python攻城狮
2018/08/23
1.5K0
Python网络爬虫(四)- XPath1.XPath2.XPath在python中的应用
axis和cxf集成Springmvc的使用
新建工程--》选择wsdl文件--》右键选择Webservice--->Generate Java Bean Skeleton
JQ实验室
2022/02/09
1K0
axis和cxf集成Springmvc的使用
Xpath、Jsoup、Xsoup(我的Java爬虫之二)
XPath是W3C的一个标准。它最主要的目的是为了在XML1.0或XML1.1文档节点树中定位节点所设计。 XPath是一种表达式语言,它的返回值可能是节点,节点集合,原子值,以及节点和原子值的混合等。
全栈程序员站长
2022/06/29
2K0
方法关键字SoapRequestMessage,SoapTypeNameSpace,SqlName,SqlProc
当多个web方法具有相同的SoapAction时使用此方法。 在默认场景中,该关键字指定请求消息的SOAP正文中的顶级元素的名称。 仅适用于定义为web服务或web客户端的类。
用户7741497
2022/07/07
3690
Python:非结构化数据-XPath
XPath 全称为 Xml Path Language,即 Xml 路径语言,是一种在 Xml 文档中查找信息的语言。它提供了非常简洁的路径选择表达式,几乎所有的节点定位都可以用它来选择。
HLee
2021/06/11
2.3K0
Python:非结构化数据-XPath
Python之xpath
  绝对路径(absolute path)必须用”/”起首,后面紧跟根节点,比如/step/step/…
全栈程序员站长
2022/07/14
4760
JavaWeb08-XML,tomcat,HTTP轻松入门
XML&tomcat&HTTP 一.XML基础知识 1. xml介绍 XML 指可扩展标记语言(EXtensible Markup Language),也是一种标记语言,很类似 HTML.它的设计宗旨是传输数据,而非显示数据它;标签没有被预定义,需要自行定义标签。 XML 被设计为具有自我描述性,是 W3C 的推荐标准,在电子计算机中,标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种的信息比如文章等。它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言
Java帮帮
2018/03/16
1.1K0
JavaWeb08-XML,tomcat,HTTP轻松入门
云原生虚拟网络 tun/tap & veth-pair
以前在研究 k8s 网络的时候,很多东西都看不太懂,只是蜻蜓点水过一下,这段时间打算恶补一下虚拟网络方面的知识,感兴趣的不妨一起探讨学习一下。
luozhiyun
2022/10/04
2K0
云原生虚拟网络 tun/tap & veth-pair
【Java爬虫】007-网页内容解析:HTML解析与XML解析
HtmlCleaner是另外一款基于Java开发的HTML文档解析器,支持Xpath语法提取HTML中的节点和元素;
訾博ZiBo
2025/01/06
890
【Java爬虫】007-网页内容解析:HTML解析与XML解析
XML 的 XPath 语法
2018-06-24 11:43
walterlv
2018/09/18
1.1K0
第70节:Java中xml和tomcat
eXtendsible markup language 可扩展性语言,用来保存数据,用来配置文件,数据传输载体. 客户端->访问->服务器
达达前端
2019/07/03
1.5K0
第70节:Java中xml和tomcat
XML及相关协议
XML 是满足一组良好定义规则的格式化文本,主要由标签和文本构成,可以被储存和展现为诸如通过 HTTP 传输的消息、编程语言中的字符串、数据库中的 CLOB等文本数据形式。 【注】为了方便起见,XML 文档也被用来指应用之间的字节流、数据库中的字段、XML 信息集中的对象集合。
hotarugali
2022/02/28
1.1K0
XML及相关协议
XPath语法_java中path的作用
XPath是W3C的一个标准。它最主要的目的是为了在XML1.0或XML1.1文档节点树中定位节点所设计。目前有XPath1.0和XPath2.0两个版本。其中Xpath1.0是1999年成为W3C标准,而XPath2.0标准的确立是在2007年。W3C关于XPath的英文详细文档请见:http://www.w3.org/TR/xpath20/ 。
全栈程序员站长
2022/09/16
8.9K0
相关推荐
XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档