如何用Ansible Playbook从SOAP API响应中获取errorCode标签值?
问题:Ansible调用SOAP API后无法提取errorCode标签值
在Windows主机上使用Ansible调用SOAP API,尝试从响应中提取errorCode标签值时,收到The supplied xpath did not match any nodes错误,无法获取目标值。
原Playbook
--- - name: execute soap api ansible.windows.win.uri: url: "" method: POST body: | < body of the soap> headers: Content-Type: "text/xml: charset=utf-8" status_code: 200 return_content: yes validate_certs: false register: api_response - name: set the content of the file ansible.windows.win.copy: content: "{{ api_response.content }}" dest: C:\Temp\response.xml - name: get result from xml community.windows.win.xml: path: C:\Temp\response.xml content: "xml" xpath: "/S:Envelope/S:Body/ns10:xyz/retrun/responseservice:status/responseservice:errorCode" register: soap_result - name: display soap result debug: var: soap_result
SOAP API响应示例
"<?xml version='1.0' encoding='UTF-8'?> <S:Envelope xmlns:S=\" ***\"> <S:Body> <ns10:xyz xmlns:responseservice=\" ***\"> <return> <responseservice:status> <responseservice:errorCode>0</responseservice:errorCode> </responseservice:status> </return> </ns10:xyz> </S:Body> </S:Envelope>"
错误信息
msg: "The supplied xpath did not match any nodes. If this is unexpected , check your xpath is valid for the xml file at supplied path"
问题原因
- XPath拼写错误:原XPath中的
retrun是拼写错误,正确应为return - 命名空间未声明:
win.xml模块无法自动识别XML中的命名空间前缀(如S:、ns10:、responseservice:),必须显式声明所有用到的命名空间 - 请求头格式错误:原
Content-Type头的分隔符错误,应使用分号而非冒号
修正方案
方案1:修正原Playbook(保留文件写入步骤)
修正XPath拼写,添加命名空间声明,同时修复请求头格式:
--- - name: execute soap api ansible.windows.win.uri: url: "" method: POST body: | < body of the soap> headers: Content-Type: "text/xml; charset=utf-8" # 修正分隔符为分号 status_code: 200 return_content: yes validate_certs: false register: api_response - name: set the content of the file ansible.windows.win.copy: content: "{{ api_response.content }}" dest: C:\Temp\response.xml - name: get result from xml community.windows.win.xml: path: C:\Temp\response.xml content: "xml" xpath: "/S:Envelope/S:Body/ns10:xyz/return/responseservice:status/responseservice:errorCode" namespaces: S: "***" # 替换为响应中S:Envelope对应的实际URI ns10: "***" # 替换为响应中ns10:xyz对应的实际URI responseservice: "***" # 替换为响应中responseservice:status对应的实际URI register: soap_result - name: display errorCode value debug: msg: "errorCode: {{ soap_result.matches[0].'responseservice:errorCode' }}"
方案2:优化步骤(直接处理响应内容)
跳过文件写入步骤,直接处理API响应内容,减少中间环节:
--- - name: execute soap api ansible.windows.win.uri: url: "" method: POST body: | < body of the soap> headers: Content-Type: "text/xml; charset=utf-8" status_code: 200 return_content: yes validate_certs: false register: api_response - name: get result from xml content community.windows.win.xml: xmlstring: "{{ api_response.content | replace('\"', '') }}" # 移除响应外层的引号 xpath: "/S:Envelope/S:Body/ns10:xyz/return/responseservice:status/responseservice:errorCode" namespaces: S: "***" ns10: "***" responseservice: "***" register: soap_result - name: display errorCode value debug: msg: "errorCode: {{ soap_result.matches[0].'responseservice:errorCode' }}"
内容的提问来源于stack exchange,提问作者Killua11
相关产品推荐
相关产品推荐

