PHP Parse SOAP XML Response
xpath is your friend:
xpath('//Row');
Full example:
$soap = <<< LOL
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header />
<SOAP-ENV:Body>
<ns3:GetDistrictByAddressResponse xmlns:ns3="http://il/co/bar/webservices/getdistrictbyaddress">
<TimeFrameTable>
<CustomerNumber>250</CustomerNumber>
<Row>
<WindowDate>10052016</WindowDate>
<WeekDay>Sunday</WeekDay>
<FromHour>1130</FromHour>
<ToHour>1430</ToHour>
</Row>
<Row>
<WindowDate>10052016</WindowDate>
<WeekDay>Sunday</WeekDay>
<FromHour>1430</FromHour>
<ToHour>1730</ToHour>
</Row>
</TimeFrameTable>
</ns3:GetDistrictByAddressResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
LOL;
$xml = simplexml_load_string($soap);
foreach ($xml->xpath('//Row') as $item)
{
print_r($item);
}
Output:
SimpleXMLElement Object
(
[WindowDate] => 10052016
[WeekDay] => Sunday
[FromHour] => 1130
[ToHour] => 1430
)
SimpleXMLElement Object
(
[WindowDate] => 10052016
[WeekDay] => Sunday
[FromHour] => 1430
[ToHour] => 1730
)
Ideone Demo
How to parse SOAP XML with Python?
The issue here is dealing with the XML namespaces:
import requests
from xml.etree import ElementTree
response = requests.get('http://www.labs.skanetrafiken.se/v2.2/querystation.asp?inpPointfr=yst')
# define namespace mappings to use as shorthand below
namespaces = {
'soap': 'http://schemas.xmlsoap.org/soap/envelope/',
'a': 'http://www.etis.fskab.se/v1.0/ETISws',
}
dom = ElementTree.fromstring(response.content)
# reference the namespace mappings here by `<name>:`
names = dom.findall(
'./soap:Body'
'/a:GetStartEndPointResponse'
'/a:GetStartEndPointResult'
'/a:StartPoints'
'/a:Point'
'/a:Name',
namespaces,
)
for name in names:
print(name.text)
The namespaces come from the xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
and xmlns="http://www.etis.fskab.se/v1.0/ETISws"
attributes on the Envelope
and GetStartEndPointResponse
nodes respectively.
Keep in mind, a namespace is inherited by all children nodes of a parent even if the namespace isn't explicitly specified on the child's tag as <namespace:tag>
.
Note: I had to use response.content
rather than response.body
.
How to parse this XML SOAP response to a POJO?
The cleanest solution I found was using JSOUP:
private <T> T parseResponse(HttpEntity entity, Class<T> typeTarget) throws Exception {
try {
String xmlSoapResponse = EntityUtils.toString(entity, StandardCharsets.UTF_8);
String xmlRetorno = extractXmlElement(xmlSoapResponse, "retorno");
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
xmlMapper.registerModule(new JavaTimeModule());
return xmlMapper.readValue(xmlRetorno.toString(), typeTarget);
} catch (Exception e) {
throw new Exception("Fail during parser", e);
}
}
private String extractXmlElement(String xmlString, String nodeTagNameElement) {
Document document = Jsoup.parse(xmlString, "", Parser.xmlParser());
document.outputSettings().prettyPrint(false);
Elements retorno = document.getElementsByTag(nodeTagNameElement);
return retorno.toString();
}
PHP Parsing a SOAP XML
Here i am using DOMDocument
to parse soap response.
Try this code snippet here
<?php
ini_set('display_errors', 1);
$string='<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:ServiceQualification">
<SOAP-ENV:Body>
<ns1:AddressSearchResponse xmlns:ns1="urn:ServiceQualification">
<return xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="tns:ServiceQualificationResponse[1]">
<item xsi:type="tns:ServiceQualificationResponse">
<status_code xsi:type="xsd:string">1</status_code>
<property_id xsi:type="xsd:string">253323</property_id>
<unit_no xsi:type="xsd:string">Basement</unit_no>
<house_no xsi:type="xsd:string">8</house_no>
<lot_no xsi:type="xsd:string">3</lot_no>
<street_name xsi:type="xsd:string">Harbour</street_name>
<street_type xsi:type="xsd:string">Road</street_type>
<suburb xsi:type="xsd:string">Hamilton</suburb>
<state_name xsi:type="xsd:string">QLD</state_name>
<postcode xsi:type="xsd:string">4007</postcode>
<estate_name xsi:type="xsd:string">Hamilton Harbour</estate_name>
<stage xsi:type="xsd:string"></stage>
<property_class xsi:type="xsd:string">Class 3</property_class>
</item>
</return>
</ns1:AddressSearchResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
$domDocument = new DOMDocument();
$domDocument->loadXML($string);
$carriers=array();
$results=$domDocument->getElementsByTagName("item");
foreach($results as $result)
{
foreach($result->childNodes as $node)
{
if($node instanceof DOMElement)
{
array_push($carriers, $node->textContent);
}
}
}
print_r($carriers);
Output:
Array
(
[0] => 1
[1] => 253323
[2] => Basement
[3] => 8
[4] => 3
[5] => Harbour
[6] => Road
[7] => Hamilton
[8] => QLD
[9] => 4007
[10] => Hamilton Harbour
[11] =>
[12] => Class 3
)
Parse XML data from PHP SOAP Response
This is the usual problem of having various namespaces which you need to navigate around. The root node defines xmlns:soap
so you can use that without having to do anything, so the XPath uses //soap:Body/*
to find the element inside the body tag, as xpath()
returns a list of matching nodes, use [0]
to just pick the only one out.
As the body data is all under a default namespace (defined as xmlns="http://webservice.nada.com/"
) you can extract all of them using $data->children("http://webservice.nada.com/")
. This now allows you to use standard object notation to access the values.
One thing to note is although echo
automatically converts it to a string, if you use these values elsewhere - you may need to convert it using (string)
as the item is in fact a SimpleXMLElement.
$data = <<< XML
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<getDefaultVehicleAndValueByVinResponse xmlns="http://webservice.nada.com/">
<getDefaultVehicleAndValueByVinResult>
<Uid>1182699</Uid>
<VehicleYear>2015</VehicleYear>
<MakeCode>47</MakeCode>
</getDefaultVehicleAndValueByVinResult>
</getDefaultVehicleAndValueByVinResponse>
</soap:Body>
</soap:Envelope>
XML;
$xml = simplexml_load_string($data);
$data = $xml->xpath("//soap:Body/*")[0];
$details = $data->children("http://webservice.nada.com/");
echo (string)$details->getDefaultVehicleAndValueByVinResult->VehicleYear;
How to parse soap xml response in php and get the information from the string
Another possible solution is to use for example SimpleXML. You can register the namespace and use an xpath expression:
$source = <<<SOURCE
<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetInfoFromSendingResponse xmlns="http://test.test.com/">
<GetInfoFromSendingResult>{"SendingID":"2468","Subject":"Test","ID":"2468","CampaignID":"890","ForwardAddress":"test@test.ro","SendingTime":"1/14/2016 8:00:00 AM","SendLeadsToEmail":"0","LanguageID":"6","LeadsTestMode":true,"WebversionLink":"","Language":"FR"}</GetInfoFromSendingResult>
</GetInfoFromSendingResponse>
</soap:Body>
</soap:Envelope>
SOURCE;
$xml = simplexml_load_string($source);
$xml->registerXPathNamespace('test', 'http://test.test.com/');
$elements = $xml->xpath('//soap:Envelope/soap:Body/test:GetInfoFromSendingResponse/test:GetInfoFromSendingResult');
$result = json_decode($elements[0], true);
print_r($result);
Will result in:
Array
(
[SendingID] => 2468
[Subject] => Test
[ID] => 2468
[CampaignID] => 890
[ForwardAddress] => test@test.ro
[SendingTime] => 1/14/2016 8:00:00 AM
[SendLeadsToEmail] => 0
[LanguageID] => 6
[LeadsTestMode] => 1
[WebversionLink] =>
[Language] => FR
)
Related Topics
Laravel PHP Fatal Error: Require(): Failed Opening Required ... Bootstrap/Autoload.Php on Line 17
Laravel Eloquent Sum of Multiplied Columns
Codeigniter - Show Information in Modal Window
Laravel Composer Sees Wrong PHP Version
On a Function That Gets Settings from a Db I Ran into the Error
Laravel Ajax Response Return HTML Elements
Should We Ever Check For MySQLi_Connect() Errors Manually
Show a Number to Two Decimal Places
Mysql Return Result If 0 Rows Returned
Regex Optionally Match a Pattern Multiple Times
How to Set Current Date as Default Value of an Input
Finding the Longest Gap Between Multiple Intervals
Undefined Index: User_Id. Where, User_Id Is Session Variable