如何通过XPath从XML中提取带条件的多个参数?
解决带条件的XML数据提取问题
原XPath的问题分析
你的无效XPath存在以下几个关键错误:
- 未处理命名空间:XML中的
s:Envelope、s:Body及其他元素带有命名空间,直接使用无命名空间的路径无法匹配元素 - 路径逻辑错误:
PtcId是SeatAssignDisplay的直接子元素,原路径错误将其放在Origin下 - 条件语法错误:直接在路径后追加
/PtcId=1不符合XPath条件筛选规则,正确做法是用[条件]筛选父元素 - 硬编码索引限制结果:
[1]强制只取第一个匹配项,无法获取所有符合PtcId=1的元素
正确的解决方案
方案1:处理命名空间的标准XPath
首先需要为XML中的命名空间声明别名:
s:http://schemas.xmlsoap.org/soap/envelope/d:departurecontrol.YYZ.com/v1(默认命名空间)c:contracts.base.test.com/v1(另一个默认命名空间)
定位符合条件的元素
先筛选出所有PtcId=1的SeatAssignDisplay元素:
//s:Envelope/s:Body/d:RetrievePaxAndSeatsByFlightResponse/d:RetrievePaxAndSeatsByFlightResult/d:AssignedSeats/d:SeatAssignDisplay[d:PtcId='1']
提取目标字段
分别提取所需参数的文本值:
- 提取CarrierCode:
//s:Envelope/s:Body/d:RetrievePaxAndSeatsByFlightResponse/d:RetrievePaxAndSeatsByFlightResult/d:AssignedSeats/d:SeatAssignDisplay[d:PtcId='1']/d:CarrierCode/text()
- 提取DepartureDate:
//s:Envelope/s:Body/d:RetrievePaxAndSeatsByFlightResponse/d:RetrievePaxAndSeatsByFlightResult/d:AssignedSeats/d:SeatAssignDisplay[d:PtcId='1']/d:DepartureDate/text()
- 提取Destination:
//s:Envelope/s:Body/d:RetrievePaxAndSeatsByFlightResponse/d:RetrievePaxAndSeatsByFlightResult/d:AssignedSeats/d:SeatAssignDisplay[d:PtcId='1']/d:Destination/text()
- 提取OperatingFlightNumber:
//s:Envelope/s:Body/d:RetrievePaxAndSeatsByFlightResponse/d:RetrievePaxAndSeatsByFlightResult/d:AssignedSeats/d:SeatAssignDisplay[d:PtcId='1']/d:OperatingFlightNumber/text()
方案2:忽略命名空间的简化XPath(部分工具支持)
如果使用的XPath工具支持local-name()函数,可以绕过命名空间检查,简化表达式:
定位符合条件的元素
//*[local-name()='SeatAssignDisplay'][*[local-name()='PtcId']='1']
提取目标字段
- 提取CarrierCode:
//*[local-name()='SeatAssignDisplay'][*[local-name()='PtcId']='1']/*[local-name()='CarrierCode']/text()
- 提取DepartureDate:
//*[local-name()='SeatAssignDisplay'][*[local-name()='PtcId']='1']/*[local-name()='DepartureDate']/text()
- 提取Destination:
//*[local-name()='SeatAssignDisplay'][*[local-name()='PtcId']='1']/*[local-name()='Destination']/text()
- 提取OperatingFlightNumber:
//*[local-name()='SeatAssignDisplay'][*[local-name()='PtcId']='1']/*[local-name()='OperatingFlightNumber']/text()
提取结果
针对你提供的XML示例,使用上述XPath会得到以下结果:
- CarrierCode:
xx - DepartureDate:
2024-08-19T00:00:00 - Destination:
RRR - OperatingFlightNumber:
102
内容的提问来源于stack exchange,提问作者Lalmani Kashyap
相关产品推荐
相关产品推荐

