Turn a SOAP response into JSON
Call a SOAP service and hand a clean JSON document to a REST client, a script or a web page.
curl -fs -H 'Content-Type: text/xml' --data-binary @get-order.xml https://erp.example.com/OrderService \
| bafi -f xml -t order-json.tmpl
The SOAP response
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:m="http://example.com/orders">
<soap:Body>
<m:GetOrderResponse>
<m:Order id="1001">
<m:Customer>Alice Smith</m:Customer>
<m:Total currency="EUR">120.50</m:Total>
</m:Order>
</m:GetOrderResponse>
</soap:Body>
</soap:Envelope>
What bafi sees
Namespace prefixes are dropped (soap:Body is Body); namespace declarations show up as attributes
(-soap, -m). Print the parsed structure whenever you are unsure of a path:
bafi -i response.xml -t '?{{toJSON .Envelope.Body}}'
{
"GetOrderResponse": {
"Order": {
"-id": "1001",
"Customer": "Alice Smith",
"Total": {
"#text": "120.50",
"-currency": "EUR"
}
}
}
}
Template
{{- with .Envelope.Body.GetOrderResponse.Order -}}
{"id": {{index . "-id"}}, "customer": {{toJSON .Customer}}, "total": {{index .Total "#text"}}, "currency": {{toJSON (index .Total "-currency")}}}
{{- end}}
cat response.xml | bafi -f xml -t order-json.tmpl
{"id": 1001, "customer": "Alice Smith", "total": 120.50, "currency": "EUR"}
with sets the dot to the order, so the template does not repeat the long path. If the service can
return a SOAP fault instead, test for it with {{if .Envelope.Body.Fault}}...{{end}}.
Related: REST response to SOAP request ยท XML to JSON