Incorrect PHP SOAP Formatting - php

I am trying to make use of the stand soapClient for PHP. I can make a class successfully using SOAP UI however when I trry and make that call using PHP this is the difference.
<arrInputs xsi:type="ns1:KeyValueArrayInput" SOAP-ENC:arrayType="ns1:KeyValueArray[]" >
<item xsi:type="ns1:KeyValueArray">
<Key xsi:type="xsd:string">Realm</Key>
<Value xsi:type="xsd:string">test</Value>
</item>
<item xsi:type="ns1:KeyValueArray">
<Key xsi:type="xsd:string">UserName</Key>
<Value xsi:type="xsd:string">test15</Value>
</item>
Now when I try send it via the php soap client I get this.
<arrInputs SOAP-ENC:arrayType="ns1:KeyValueArray[22]" xsi:type="ns1:KeyValueArrayInput">
<item xsi:type="ns1:KeyValueArray">
<Key xsi:type="xsd:string">Realm</Key>
<Value xsi:type="xsd:string">test</Value>
</item>
<item xsi:type="ns1:KeyValueArray">
<Key xsi:type="xsd:string">UserName</Key>
<Value xsi:type="xsd:string">test2</Value>
</item>
Any suggestions as to how the type and the array type have been switched around. If I put the type in front of the arrayType all is good.
$creationFields = array();
$creationFields['strSessionID'] = $this->getSessionHash();
$arrInputs = array();
foreach ($params as $k => $v)
{
$arrInputs[] = array('Key' => $k, 'Value' => $v);
}
$creationFields['arrInputs'] = $arrInputs;
__soapCall('methodName', $creationFields);
This is out of the WSDL:
<message name="methodName"><part name="strSessionID" type="xsd:string" /><part name="arrInputs" type="tns:KeyValueArrayInput" /></message>

Related

How to parse soap xml response that have several namespaces defined. I need to parse the Articles array returned

The soap xml reponse is as such:
<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/">
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS1="urn:TPAPIPosIntfU-ITPAPIPOS">
<NS1:GetArticlesInfoResponse xmlns:NS2="urn:TPAPIPosIntfU" xmlns:NS3="urn:TPAPIPosTypesU">
<return xsi:type="NS2:TGetArticlesInfoResponse">
<ReturnCode xsi:type="xsd:int">0</ReturnCode>
<ReturnMessage xsi:type="xsd:string">ok</ReturnMessage>
<Articles xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:TArticleInfo[x]">...</Articles>
<Extra xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:TExtraInfo[0]"/>
</return>
</NS1:GetArticlesInfoResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
And this is the Articles array that i need to parse:
<item xsi:type="NS3:TArticleInfo">
<ArticleId xsi:type="xsd:long">5000001716</ArticleId>
<ArticleName xsi:type="xsd:string">Coca Cola</ArticleName>
<ArticleNumber xsi:type="xsd:int">1</ArticleNumber>
<Available xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="xsd:long[3]">
<item>5000000210</item>
<item>5000000208</item>
<item>5000000209</item>
</Available>
<DepartmentId xsi:type="xsd:long">5000000170</DepartmentId>
<Prices xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:TItemPrice[2]">
<item xsi:type="NS3:TItemPrice">
<ArticleId xsi:type="xsd:long">5000001716</ArticleId>
<PriceId xsi:type="xsd:long">5000000206</PriceId>
<Amount xsi:type="xsd:double">2</Amount>
<Vat xsi:type="xsd:double">21</Vat>
<Extra xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:TExtraInfo[0]"/>
</item>
<item xsi:type="NS3:TItemPrice">
<ArticleId xsi:type="xsd:long">5000001716</ArticleId>
<PriceId xsi:type="xsd:long">5000000207</PriceId>
<Amount xsi:type="xsd:double">1.7</Amount>
<Vat xsi:type="xsd:double">12</Vat>
<Extra xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:TExtraInfo[0]"/>
</item>
</Prices>
<FreeOption xsi:type="xsd:long">5000000145</FreeOption>
<Options xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="xsd:long[1]">
<item>5000000143</item>
</Options>
<IsMenu xsi:type="xsd:boolean">false</IsMenu>
<IsManualPrice xsi:type="xsd:boolean">false</IsManualPrice>
<IsActive xsi:type="xsd:boolean">true</IsActive>
<Promo xsi:type="xsd:boolean">false</Promo>
<HqId xsi:type="xsd:string">Coca Cola</HqId>
<Extra xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:TExtraInfo[5]">
<item xsi:type="NS3:TExtraInfo">
<Key xsi:type="xsd:string">daily_stock_active</Key>
<Value xsi:type="xsd:string">0</Value>
<Extra xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:TExtraInfo[0]"/>
</item>
<item xsi:type="NS3:TExtraInfo">
<Key xsi:type="xsd:string">daily_stock_qty</Key>
<Value xsi:type="xsd:string">0</Value>
<Extra xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:TExtraInfo[0]"/>
</item>
<item xsi:type="NS3:TExtraInfo">
<Key xsi:type="xsd:string">purchase_price</Key>
<Value xsi:type="xsd:string">0.0000</Value>
<Extra xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:TExtraInfo[0]"/>
</item>
<item xsi:type="NS3:TExtraInfo">
<Key xsi:type="xsd:string">course_id</Key>
<Value xsi:type="xsd:string">5000001331</Value>
<Extra xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:TExtraInfo[0]"/>
</item>
<item xsi:type="NS3:TExtraInfo">
<Key xsi:type="xsd:string">info</Key>
<Value xsi:type="xsd:string"/>
<Extra xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:TExtraInfo[0]"/>
</item>
</Extra>
</item>
Parameter Type Description
ArticleId Long Internal Id of this Article
ArticleName String Name of this Article
ArticleNumber Integer Number of this Article
Available [Long] List of Sales Area Id's where this Article is available
Prices [ItemPrice] List of Prices for this Article
DepartmentId Long Id of the Department where this Article belongs to
FreeOption Long Free Option ID
Options [Long] List of must-have options
IsMenu Boolean Returns true if this Article is a menu
IsManualPrice Boolean Returns true if this Article requires a manual price input when ordered
IsActive Boolean Returns if true is this Article is active
Promo Boolean Return true if this Article is a Cobmo/Promo article
HqId String HQ Id
Extra [ExtraInfo] List of extra fields
List of available extra fields:
Key Description
course_id Only return articles of a specific course
daily_stock_active 1/0 (if DailyStock=1 was specified in request’s Extra fields)
daily_stock_qty Daily stock quantity (if DailyStock=1 was specified in request’s Extra fields)
info Article info (tab 9 of the article settings in back-office)
plu When PLU is not zero
purchase_price Purchase price
ArticleShort
ArticleShort Object
<item xsi:type="NS3:TArticleShort">
<ArticleId xsi:type="xsd:long">5000001716</ArticleId>
<ArticleName xsi:type="xsd:string">Coca Cola</ArticleName>
<ArticleNumber xsi:type="xsd:int">1</ArticleNumber>
<SalesAreaId xsi:type="xsd:long">5000000210</SalesAreaId>
<DepartmentId xsi:type="xsd:long">5000000170</DepartmentId>
<HqId xsi:type="xsd:string">Coca Cola</HqId>
<Extra xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:TExtraInfo[0]"/>
</item>
How can I parse this soap XML response in php curl to get the Articles array data? I have tried SimpleXMLElement but I am unable to parse this.
I have surfed a lot for answers but not able to get the correct parsing technique. Shall I use Xpaths if yes, then how to create an XPath to parse the articles array?
A simple solution using XPath and SimpleXML, which from the look of the XML doesn't involve namespaces for the XPath itself. This loads the XML and then looks for an element called <return> with a direct descendant called <Articles>. As xpath() returns a list of nodes, it then just picks the first one (using [0]) and iterates of the <item> elements enclosed and outputs the <ArticleId> elements value....
$xml = simplexml_load_string($data);
$articles = $xml->xpath("//return/Articles");
foreach ( $articles[0]->item as $item ) {
echo (string)$item->ArticleId.PHP_EOL;
}
With the test data this gives...
5000001716
5000001716

phpClient returning nesting XML

I have returning data from webservice with soap like this :
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header/>
<soap-env:Body>
<n0:ZFIFM_VIRTUAL_ACCOUNTResponse xmlns:n0="urn:sap-com:document:sap:rfc:functions">
<BILLDETAILS>
<item>
<BILLCODE>?</BILLCODE>
<BILLNAME>?</BILLNAME>
<BILLSHORTNAME>?</BILLSHORTNAME>
<BILLAMOUNT>?</BILLAMOUNT>
</item>
<item>
<BILLCODE>01</BILLCODE>
<BILLNAME>BIL</BILLNAME>
<BILLSHORTNAME>Billing</BILLSHORTNAME>
<BILLAMOUNT>114509000</BILLAMOUNT>
</item>
<item>
<BILLCODE>02</BILLCODE>
<BILLNAME>TAX</BILLNAME>
<BILLSHORTNAME>PPN 10%</BILLSHORTNAME>
<BILLAMOUNT>11450900</BILLAMOUNT>
</item>
<item>
<BILLCODE>03</BILLCODE>
<BILLNAME>TAX</BILLNAME>
<BILLSHORTNAME>PPL WAPU</BILLSHORTNAME>
<BILLAMOUNT>11450900</BILLAMOUNT>
</item>
<item>
<BILLCODE>04</BILLCODE>
<BILLNAME>TAX</BILLNAME>
<BILLSHORTNAME>PPK 4.2</BILLSHORTNAME>
<BILLAMOUNT>6758400</BILLAMOUNT>
</item>
<item>
<BILLCODE>05</BILLCODE>
<BILLNAME>TAX</BILLNAME>
<BILLSHORTNAME>PPJ 23 - 2%</BILLSHORTNAME>
<BILLAMOUNT>193500</BILLAMOUNT>
</item>
<item>
<BILLCODE>06</BILLCODE>
<BILLNAME>TAX</BILLNAME>
<BILLSHORTNAME>PPO 23 - 15%</BILLSHORTNAME>
<BILLAMOUNT>5587500</BILLAMOUNT>
</item>
</BILLDETAILS>
<BILLINFO1>1000000014</BILLINFO1>
<BILLINFO2>YOU MEAN IT</BILLINFO2>
<BILLINFO3>1140000000</BILLINFO3>
<BILLINFO4>JOJO Heart</BILLINFO4>
<CURRENCY>360</CURRENCY>
<STATUS>
<item>
<ISERROR>?</ISERROR>
<ERRORCODE>?</ERRORCODE>
<STATUSDESCRIPTION>?</STATUSDESCRIPTION>
</item>
<item>
<ISERROR>false</ISERROR>
<ERRORCODE>00</ERRORCODE>
<STATUSDESCRIPTION>Success</STATUSDESCRIPTION>
</item>
</STATUS>
</n0:ZFIFM_VIRTUAL_ACCOUNTResponse>
</soap-env:Body>
</soap-env:Envelope>
the problem is how can I get array of BILLDETAILS while I'm using this method to call soapCLient :
$x = $client->ZFIFM_VIRTUAL_ACCOUNT(array("BILLKEY1"=>"8871711140100014"));
I already try with count($x->BILlDETAILS) but it's only return 1 values, and when I echo with : echo $x->BILLDETAILS[0];
it print blank..
please i need an advice..
thanks..
Try it like this:
foreach ($x->BILLDETAILS->item as $key => $item) {
var_dump($item);
}

need help.. php soap

I have a xml document, i need to get name attribute's value with helping php. the xml file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:GetGoodsTreeResponse xmlns:ns2="http://b2b.alta.com.ge" xmlns:ns3="http://192.168.0.10/b2b">
<ns3:GoodsTree level="0">
<item id="010000000017337" level="0" name="COMPUTERS" is_open="N">
<item id="015000000030431" level="1" name="ALTA" is_open="Y">
<item id="015000000030443" level="2" name="Zakaznoe Izdelie" is_open="N"/>
<item id="015002000031034" level="2" name="ATOM" is_open="N"/>
<item id="015005000030453" level="2" name="Celeron" is_open="N"/>
<item id="015010000030432" level="2" name="Dual Core" is_open="N"/>
<item id="015150000030778" level="2" name="i3" is_open="N"/>
<item id="015220000030775" level="2" name="i5" is_open="N"/>
<item id="015300000031827" level="2" name="i7" is_open="N"/>
</item>
<item id="010001005030300" level="1" name="Apple" is_open="N"/>
<item id="010001001033496" level="1" name="Asus" is_open="N"/>
<item id="010001001015793" level="1" name="Fujitsu" is_open="N"/>
<item id="010001002015166" level="1" name="HP Compaq" is_open="N"/>
</item>
</ns3:GoodsTree>
</ns2:GetGoodsTreeResponse>
</S:Body>
</S:Envelope>
please help me i dont know what to do.. sorry for my english.
You can use DOMDocument to parse that XML and get all items using DOMXpath, then loop in all items and get the attributes based on position (id = 0, name = 2), then create an new array that will hold all you item id's with their names:
$dom = new DOMDocument;
$dom->loadXML($xml);
$xpath = new DOMXPath($dom);
$xpath->registerNamespace('S', 'http://schemas.xmlsoap.org/soap/envelope/');
$items = array();
$el = $xpath->query('//item');
foreach($el as $item){
$attributes = $item->attributes;
$items[$attributes->item(0)->value] = $attributes->item(2)->value;
}
var_dump($items); // $items will be an array with item id and it's value will be item name
Codepad Example

php soapserver returning better readable associative array

I'm using PHP SOAPSERVER class.
As a response I'm sending associative php array:
function getItems()
{
...
$items[] = Array("itemID" =>$itemID,"itemName"=>$itemName);
return $items;
}
SOAP return is like this:
...
<Items>
<item type="Map">
<item>
<key type="string">
itemID
</key>
<value type="string">
17558
</value>
</item>
<item>
<key type="string">
itemName
</key>
<value type="string">
I-17558
</value>
</item>
</item>
</Items>
...
Such return is pretty hard to analyze for human (given bigger array).
The preferred form would be like this:
...
<Items>
<item>
<itemID>17558</itemID>
<itemName>I-17558</itemName>
</item>
<item>
<itemID>17559</itemID>
<itemName>I-17559</itemName>
</item>
</Items>
...
Is such SOAP return possible (not changing the return type - array)? How?
I have just started with SOAP and most tutorials show how to return simple types like string.
Instead of sending an associative array, send a stdclass object.
Example :
$return = new stdclass;
$return->ItemID = 1;
$return->ItemName = 'foo';
return $return;
Then the SOAP results will be just the way you want it!

How to query graphml using php, DomDocument and DomXPath?

Does someone know how to query a graphml document with php, DomDocument and DomXpath?
My query seems to be correct.
e.g. //graphml/graph/node
$dom = new DomDocument();
$dom->load("doc.graphml");
$x = new DOMXPath($dom);
$x->registerNamespace('y', "http://www.yworks.com/xml/graphml");
$r = $x->query("//graphml/graph/node");
echo $r->length;
The returned length is always 0;
But it has to be 1.
XML:
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:y="http://www.yworks.com/xml/graphml"
xmlns:yed="http://www.yworks.com/xml/yed/3"
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yFiles for Java 2.8-->
<key for="graphml" id="d0" yfiles.type="resources"/>
<key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/>
<key for="port" id="d3" yfiles.type="portuserdata"/>
<key attr.name="url" attr.type="string" for="node" id="d4"/>
<key attr.name="description" attr.type="string" for="node" id="d5"/>
<key for="node" id="d6" yfiles.type="nodegraphics"/>
<key attr.name="Beschreibung" attr.type="string" for="graph" id="d7">
<default/>
</key>
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G">
<node id="n0">
<data key="d4"><![CDATA[http://www.vilauma.de/]]></data>
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="30.0" x="785.0" y="-15.0"/>
<y:Fill color="#FFCC00" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="45.349609375" x="-7.6748046875" y="5.6494140625">vilauma</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</graphml>
Solved my question!
$dom = new DomDocument();
$dom->load("doc.graphml");
$x = new DOMXPath($dom);
$x->registerNamespace("graphml", "http://graphml.graphdrawing.org/xmlns");
$r = $x->query("//graphml:node");
echo $r->length; // result => 1

Categories