I am getting a SOAP response for a SOAP call perfectly using SOAP ui but when I call the same in php, I am not able to traverse to the desired element(CreditId in this case), which I want.
The following is the SOAP response that I get using SOAP ui :
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header/>
<soap-env:Body>
<n0:getProjectCreditListResponse xmlns:n0="urn:sap-com:document:sap:soap:functions:mc-style">
<EUserGuid>33/XIcx+3/GxWABQVoJXWA==</EUserGuid>
<EtCurrCreditList>
<item>
<PhaseId/>
<CreditcategoryDescrption>Project Information Forms</CreditcategoryDescrption>
<CreditId>CSD1GSP1L-1000008140</CreditId>
</item>
<item>
<PhaseId/>
<CreditcategoryDescrption>Project Information Forms</CreditcategoryDescrption>
<CreditId>CSD1GSP2L-1000008140</CreditId>
</item>
</EtCurrCreditList>
<EtErrorLogInfo/>
</n0:getProjectCreditListResponse>
</soap-env:Body>
</soap-env:Envelope>
Now I have gone through the various similar questions on the site, where it is advised to do like this to get the desired element :
$client = new SoapClient('wsdl file path',array('trace'=>1,'exceptions'=>1);
$res = $client->getCreditFormDataXml(array(input arguments));
$xml = simplexml_load_string($res);
$xml->registerXPathNamespace('soap-env', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('n0', 'urn:sap-com:document:sap:soap:functions:mc-style');
foreach ($xml->xpath('//EtCurrCreditList//item//CreditId') as $item)
{
var_dump($item);
}
However I get an error stating that
Warning: simplexml_load_string() expects parameter 1 to be string
I have tried converting the $res variable to a string but it gives an error that
Object of class stdClass could not be converted to string
But if I do var_dump($res), I get output like this :
object(stdClass)[2]
public 'EUserGuid' => string 'ß×!Ì~ßñ±X�PV‚WX' (length=16)
public 'EtCurrCreditList' =>
object(stdClass)[3]
public 'EtErrorLogInfo' =>
object(stdClass)[4]
Why is the code not going to the sub nodes of the EtCurrCreditList so that I can then process it to get the desired value. - Solved
Final Output :
stdClass Object
(
[EUserGuid] => ß×!Ì~ßñ±XPV‚WX
[EtCurrCreditList] => stdClass Object
(
[item] => Array
(
[0] => stdClass Object
(
[PhaseId] =>
[PhaseDescription] =>
[CreditcategoryId] => CSD1GSL-1000008140
[CreditcategoryDescrption] => Project Information Forms
[CreditId] => CSD1GSP1L-1000008140
)
[1] => stdClass Object
(
[PhaseId] =>
[PhaseDescription] =>
[CreditcategoryId] => CSD1GSL-1000008140
[CreditcategoryDescrption] => Project Information Forms
[CreditId] => CSD1GSP2L-1000008140
)
[2] => stdClass Object
(
[PhaseId] =>
[PhaseDescription] =>
[CreditcategoryId] => CSD1GSL-1000008140
[CreditcategoryDescrption] => Project Information Forms
[CreditId] => CSD1GSP3L-1000008140
)
)
)
[EtErrorLogInfo] => stdClass Object
(
)
use echo"<pre>";print_r($res); you will be better able to understand how to traverse or show us the result.
$res=stdClass Object ( [EUserGuid] => ß×!Ì~ßñ±XPV‚WX [EtCurrCreditList] => stdClass Object ( ) [EtErrorLogInfo] => stdClass Object ( ) )
Now use
foreach($res->EUserGuid as $data)
{
//Your logic
}
same for EtCurrCreditList and EtErrorLogInfo and also nested loops if these object contain anything.
updating according to your new output.
you can iterate it like this
$res->EUserGuid=$something;
foreach($res->EtCurrCreditList->item as $eachItem)
{
$eachItem->PhaseId=$your_ wish;
$eachItem->PhaseDescription==$your_ wish;
$eachItem->CreditcategoryId==$your_ wish;
$eachItem->CreditcategoryDescrption==$your_ wish;
$eachItem->CreditId=$your_ wish;
}
and can ignore EtErrorLogInfo
Related
I'm using the namecheap API to do some stuff, it's the first time I've used a API and I'm running into a bit of a problem.
This is what I have so far:
$ApiKey = "**********************";
$ApiUser = "*****";
$UserName = "*********";
$ClientIP = "********";
$NamecheapURI = "https://api.namecheap.com/xml.response";
$executionURL = $NamecheapURI."?ApiUser=".$ApiUser."&ApiKey=".$ApiKey."&UserName=".$UserName."&Command=namecheap.domains.check&ClientIp=".$ClientIP."&DomainList=".$domain;
$xml = simplexml_load_file($executionURL);
print_r($xml);
When print $xml I am returned simple XML objects:
SimpleXMLElement Object
(
[#attributes] => Array
(
[Status] => OK
)
[Errors] => SimpleXMLElement Object
(
)
[Warnings] => SimpleXMLElement Object
(
)
[RequestedCommand] => namecheap.domains.check
[CommandResponse] => SimpleXMLElement Object
(
[#attributes] => Array
(
[Type] => namecheap.domains.check
)
[DomainCheckResult] => SimpleXMLElement Object
(
[#attributes] => Array
(
[Domain] => facebook.com
[Available] => false
[ErrorNo] => 0
[Description] =>
[IsPremiumName] => false
[PremiumRegistrationPrice] => 0
[PremiumRenewalPrice] => 0
[PremiumRestorePrice] => 0
[PremiumTransferPrice] => 0
[IcannFee] => 0
[EapFee] => 0
)
)
)
[Server] => PHX01APIEXT03
[GMTTimeDifference] => --5:00
[ExecutionTime] => 0.008
)
My question is beyond this, how do I move forward and pull data from this?
I've tried treating this as an array but I am getting nowhere, when using is_array() to test if it was an array it says it's not which I don't understand...
I apologise if this is a noob question, I am a bit new to this. In short, what do I need to do to pull data from this?
Thanks in advance!
Learning to use SimpleXML is much better than trying to convert it to arrays/json/anything else and simple (hence the name). A quick example...
$response = '<?xml version="1.0" encoding="UTF-8"?>
<CommandResponse Type="namecheap.domains.check">
<DomainCheckResult Domain="facebook.com">
<Element>1234</Element>
<Element>12345</Element>
</DomainCheckResult>
</CommandResponse>';
$xml = simplexml_load_string($response);
echo "DOmain=".$xml->DomainCheckResult['Domain'].PHP_EOL;
foreach ( $xml->DomainCheckResult->Element as $value) {
echo "Value=".(string)$value.PHP_EOL;
}
outputs...
DOmain=facebook.com
Value=1234
Value=12345
You have to adapt this to your own XML, but the idea is that if you want to access an element of an item you use object notation -> and if you need to get an attribute, use array notation [].
So in the above code, the first echo ($xml->DomainCheckResult['Domain']) gets the <DomainCheckResult> element and outputs the Domain attribute.
Then the foreach loop says fetch each <Element> within <DomainCheckResult> and output the value.
I load some XML which produces a SimpleXML Object like so (only displaying one Object)
SimpleXMLElement Object
(
[Jobs] => SimpleXMLElement Object
(
[Job] => Array
(
[0] => SimpleXMLElement Object
(
[ID] => J000001
[Name] => Internal Time
[Description] => Use this job to record your internal and non-billable time for activities such as annual leave, sick leave, professional development, staff meetings etc
[Client] => SimpleXMLElement Object
(
[ID] => 8430219
[Name] => Fake Client
)
[ClientOrderNumber] => SimpleXMLElement Object
(
)
[State] => Planned
[StartDate] => 2016-03-21T00:00:00
[DueDate] => 2017-03-21T00:00:00
[InternalID] => 11442733
[Assigned] => SimpleXMLElement Object
(
[Staff] => SimpleXMLElement Object
(
[ID] => 344460
[Name] => Som Name
)
)
)
)
)
)
What I would like to do is create an array of the client Name and client ID. So I am aiming for something like so
[data] => array (
8430219 => Fake Client,
8430343 => Another Client,
etc
)
At the moment, I can get the name in place, but struggling with the id because it says it is an illegal offset type. This is what I have
foreach($oXML->Jobs as $oEntry) {
foreach ($oEntry->Job as $data) {
$jobsArray = array(
$data->Client->ID => $data->Client->Name
);
}
}
How can I create the array based on the SimpleXML Object I have?
Thanks
First of all, to obtain your desired array you can not use this syntax:
$jobsArray = array( $key => $val );
You have to use something like this:
$jobsArray[$key] = $val;
Otherwise, at each repeating loop, your syntax will override precedent array values.
Then, I suggest you to use XPath to simplify entire process. With XPath queries, you can retrieve a set of nodes with only one search.
Assuming you have this XML:
<?xml version="1.0"?>
<Jobs>
<Job>
<Client>
<ID>8430219</ID>
<Name>Fake Client</Name>
</Client>
<Client>
<ID>8430220</ID>
<Name>Fake Client 2</Name>
</Client>
</Job>
<Job>
<Client>
<ID>8430221</ID>
<Name>Fake Client 3</Name>
</Client>
</Job>
</Jobs>
With this xpath query:
$clients = $oXML->xpath( '/Jobs/Job/Client' );
you obtain in $clients all <Client> nodes. Then you can create your array in this way:
$result = array();
foreach( $clients as $client )
{
$result[$client->ID->__toString()] = $client->Name->__toString();
}
This is $result after foreach loop:
Array
(
[8430219] => Fake Client
[8430220] => Fake Client 2
[8430221] => Fake Client 3
)
Note that we have to cast as string single nodes (that are SimpleXML objects): this is absolutely necessary creating keys, otherwise the array assignment fails. You can obtain same result using (string) $client->ID instead of $client->ID->__toString()
Read more about SimpleXMLElement::xpath
Read more about XPath
I have a XML file simillar to this :
<information version="2">
<currentTime>2014-06-06 17:28:16</currentTime>
<result>
<name>Mark</name>
<surname>Smith</surname>
</result>
I read it with php function and parse it to the object with function, like this:
function parse_data($data){
$return_data['currentTime'] = $data->currentTime;
$return_data['name'] = $data->result->name;
$return_data['surname'] = $data->result->surname;
return $return_data;
}
$xml = simplexml_load_string(file_get_contents($link));
$object = parse_data($xml);
Then, when I echo it on the screen, to check how it look:
//json_encode($xml);
{
"#attributes":{"version":"2"},
"currentTime":"2014-06-06 17:28:16",
"result":{"name":"Mark","surname":"Smith"}
}
//print_r($xml);
SimpleXMLElement Object (
[#attributes] => Array ( [version] => 2 )
[currentTime] => 2014-06-06 17:56:30
[result] => SimpleXMLElement Object (
[name] => Mark
[surname] => Smith
)
)
//json_encode($object);
{
"currentTime":{"0":"2014-06-06 17:28:16"},
"name":{"0":"Mark"},
"surname":{"0":"Smith"}
}
//print_r($object);
Array (
[currentTime] => SimpleXMLElement Object ( [0] => 2014-06-06 17:52:50 )
[name] => SimpleXMLElement Object ( [0] => Mark)
[surname] => SimpleXMLElement Object ( [0] => Smith )
)
What is wrong with my code? He seems to read the informaton in xml file as array? Because of this strange notation I cannont operate on this data normally.
It also behave like this:
echo json_encode($object['name']); will give -> {"0":"Mark"}
echo $object['name']; will give -> Mark
Can anybody help me? What am I doing wrong?
I want my $object to look like this:
//json_encode($object);
{
"currentTime":"2014-06-06 17:28:16",
"name":"Mark",
"surname":"Smith"
}
Edit1: added print_r values
Yes, as you have noticed the type returned by $someSimpleXMLNode is an object. If you want the node value (as a string for example) use:
$return_data['currentTime'] = (string)$data->currentTime;
which is the same as doing
$return_data['currentTime'] = $data->currentTime->__toString();
etc
When you do
echo $data->currentTime;
the node is automatically coerced into a string (because echo only handles strings). This is done (generally, in php) by the object's __toString method.
Data returned over SOAP is returned as objects within an array as shown below.
Array (
[LastPage] => true
[ListOfContact] => stdClass Object (
[Contact] => stdClass Object (
[ContactId] => contactID
[Description] =>
[ContactEmail] => emailAddress
)
)
)
How do i ensure that data is returned as an array only without objects? I am using the SoapClient with the NO WSDL option.
$objectArray = YOUR_OBJECT;
foreach ($objectArray['ListOfContact'] AS $contactArray)
{
$email = $contactArray['ContactEmail'];
etc...
}
Simple example, but should get you on your way!
I'm currently using file_get_contents to get an xml.
It work well and when I display the xml with the correct MIME type header('Content-type: text/xml') I obtain something like this :
<?xml version="1.0" encoding="iso-8859-1" ?>
<tarification compagnie="banane" cle="laclef">
<gamme reference="equilibre-sante">
<tarif formule="f100">Xx.xx</tarif>
<tarif formule="f200">Xx.xx</tarif>
</gamme>
</tarification>
To use it as an object I use simplexml_load_string but when I print_r the returned object I didn't see the formule attribute I just see something like this :
SimpleXMLElement Object
(
[#attributes] => Array
(
[compagnie] => banane
[cle] => laclef
)
[gamme] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[reference] => equilibre-sante
)
[tarif] => Array
(
[0] => Xx.xx
[1] => Xx.xx
)
)
)
)
I want to get formule attributes, I have already tested to do this by following this tutorial without success.
You need to use the SimpleXMLElement::attributes as:
$xml = simplexml_load_string($xmlstring);
foreach($xml->gamme->tarif as $tarif) {
foreach($tarif->attributes() as $a => $b) {
echo $a,'="',$b,"\"\n";
}
}
See it