有一个代码可以调用应用程序的Web服务。
- uri:
url: http://10.164.52.61:8080/ems/v74/ws/customer.ws?customerRefId=f4XXXb15d69c3
method: GET
content_as_json: true
password: admin
user: admin
validate_certs: no
return_content: yes
HEADER_Cookie: "{{login.set_cookie}}"
register: customerId
- debug:
var: customerId.content
样本回复是
"customerId.content": "<listResponse type=\"customer\" count=\"1\"><instance customerId=\"28\" name=\"abc\" customerRefId=\"xyz\" refId1=\"12\" type=\"org\" enabled=\"true\" phone=\"\" fax=\"\" billingZip=\"\" billingAddress=\"\" billingCity=\"\" billingCountry=\"\" billingState=\"\" vendor=\"1\" defaultEmail=\"test\" defaultContactName=\"test\"/></listResponse>"
我想在下一段代码中访问列表响应。就像我只需要&#34; customerId&#34;的价值。如何使用anisble
实现这一目标答案 0 :(得分:2)
Ansible中没有XML支持。开箱即用 您可以使用正则表达式过滤器在XML数据中进行一些简单的搜索 在您的示例中:
- debug: msg="{{ customerId.content | regex_findall('customerId=\"(\d+)\"') }}"
将搜索customerId=\"<number>\"
字符串并返回引号中的数字列表。
更新:完整的工作示例:
- hosts: localhost
gather_facts: no
vars:
myvar: "<listResponse type=\"customer\" count=\"1\"><instance customerId=\"28\" name=\"abc\" customerRefId=\"xyz\" refId1=\"12\" type=\"org\" enabled=\"true\" phone=\"\" fax=\"\" billingZip=\"\" billingAddress=\"\" billingCity=\"\" billingCountry=\"\" billingState=\"\" vendor=\"1\" defaultEmail=\"test\" defaultContactName=\"test\"/></listResponse>"
tasks:
- debug: msg="{{ myvar | regex_findall('customerId=\"(\d+)\"') }}"
我使用ansible 2.1.1.0
。
答案 1 :(得分:2)
这与sebaszw的答案类似,但是不需要将xml响应写入文件,而是将其存储在变量中。
- uri:
url: http://10.164.52.61:8080/ems/v74/ws/customer.ws?customerRefId=f4XXXb15d69c3
method: GET
content_as_json: true
password: admin
user: admin
validate_certs: no
return_content: yes
HEADER_Cookie: "{{login.set_cookie}}"
register: customerId
- xml:
xmlstring: "{{customerId.content}}"
xpath: /listResponse/instance
content: attribute
register: instance_attributes
- debug:
var: instance_attributes.matches.0.instance.customerId
答案 2 :(得分:1)
从Ansible 2.4你可以这样做:
- get_url:
url: http://10.164.52.61:8080/ems/v74/ws/customer.ws?customerRefId=f4XXXb15d69c3
dest: ./response.xml
url_password: admin
url_user: admin
validate_certs: no
headers:
Cookie: "{{login.set_cookie}}"
- xml:
path: ./response.xml
xpath: /listResponse/instance
content: attribute
register: instance_attributes
- debug:
var: instance_attributes.matches.0.instance.customerId
答案 3 :(得分:0)
值得关注ansible-xml。它不是Ansible的一部分,但它是一个非常有用的解析xml的模块,它使用了lxml
Python库。
答案 4 :(得分:0)
我刚刚在uri模块中添加了XML解析支持,因为我也需要它。 https://github.com/ansible/ansible/pull/53045
就像JSON支持一样,它将返回带有包含XML内容的字典的'xml'键,以方便访问有效负载中的数据。
您的示例如下所示:
- uri:
url: http://10.164.52.61:8080/ems/v74/ws/customer.ws?customerRefId=f4XXXb15d69c3
method: GET
password: admin
user: admin
validate_certs: no
HEADER_Cookie: "{{login.set_cookie}}"
register: customerId
- debug:
var: customerId.xml.listResponse.instance['@customerId']
customerId.xml的输出为:
{
'listResponse': {
'@type': 'customer',
'@count', '1',
'instance': {
'@customerId': '28',
'@name': 'abc'
'@customerRefId': 'xyz',
'@refId1': '12',
'@type': 'org',
'@enabled': 'true',
'@phone': '',
'@fax': '',
'@billingZip': '',
'@billingAddress': '',
'@billingCity': '',
'@billingCountry': '',
'@billingState': '',
'@vendor': '1',
'@defaultEmail': 'test',
'@defaultContactName': 'test'
}
}
}
答案 5 :(得分:0)
因为要使其正常工作这是相当复杂的,所以我认为我应该发布Ansible-XML参数来解析SOAP响应:
describe_security_groups
诀窍是正确命名空间和xpath。另外,由于我需要真实的名字,所以我需要<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<S:Body xmlns:ns2="http://ws.coverity.com/v9">
<ns2:getLdapServerDomainsResponse>
<return>
<name>soapui_test</name>
</return>
</ns2:getLdapServerDomainsResponse>
</S:Body>
</S:Envelope>
content: text
我仍然不明白为什么最后的xpath节不能与Ansible - XML docs示例所暗示的- name: Extract the name from the SOAP
xml:
xmlstring: "{{ ldap_response.content }}"
xpath: "/S:Envelope/S:Body/ns2:getLdapServerDomainsResponse/return/name"
namespaces:
S: "http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV: "http://schemas.xmlsoap.org/soap/envelope/"
ns2: "http://ws.coverity.com/v9"
content: text
register: ldap_name
一起使用。上面的.../ns2:return/ns2:name
用(简体)填充:
ldap_name