Page 1 of 2
Reading an XML Post
Posted: Sun Oct 29, 2006 11:09 pm
by kevin7654
Hey everyone,
My shipping company posts an xml file to my web server. How do I go about parsing and reading this file to extract the information from it? I'm completely lost and have no idea where to begin. I've tried reading a bit about xml and the built in php functions but they all seem to tell me how to take a url or a file and read that, but how do I tell my scrip it is coming from a post?
Thanks,
Kevin
Here's an example of the xml file:
Code: Select all
<Status AffiliateID="CP" OrderID="12345">
−
<Shipment PackageID="98765" Status="Shipped" ShipDate="2001-08-07 12:14:27.0" TrackingNumber="1ZY9W6270241234173">
<ShipMethod>FedEx-2 Day</ShipMethod>
<Item ItemID="98765-1"/>
<Item ItemID="98765-2"/>
<Item ItemID="98765-3"/>
<Item ItemID="98765-4"/>
<Item ItemID="98765-5"/>
<Item ItemID="98765-6"/>
</Shipment>
−
<Shipment PackageID="56789" Status="Shipped" ShipDate="2001-08-07 14:41:25.0">
<ShipMethod>USPS-First Class</ShipMethod>
<Item ItemID="56789-1"/>
<Item ItemID="56789-2"/>
<Item ItemID="56789-4"/>
</Shipment>
−
<Shipment PackageID="56789" Status="Processing" ShipDate="">
<ShipMethod>USPS-First Class</ShipMethod>
<Item ItemID="56789-3"/>
</Shipment>
−
<Shipment PackageID="56789" Status="Cancelled" ShipDate="">
<ShipMethod>USPS-First Class</ShipMethod>
<Item ItemID="56789-4"/>
<Item ItemID="56789-5"/>
</Shipment>
</Status>
Posted: Mon Oct 30, 2006 12:32 am
by itsmani1
Try this:
Code: Select all
$file = "tst1.xml";
function trustedFile($file)
{
return true;
}
function startElement($parser, $name, $attribs)
{
echo "<";
echo "<font color=\"#0000cc\">$name</font>";
if (count($attribs))
{
foreach ($attribs as $k => $v)
{
echo " <font color=\"#009900\">$k</font>=\"<font color=\"#990000\">$v</font>\"";
}
}
echo ">";
}
function endElement($parser, $name)
{
echo "</<font color=\"#0000cc\">$name</font>>";
}
function new_xml_parser($file)
{
global $parser_file;
$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
if (!($fp = @fopen($file, "r")))
{
return false;
}
if (!is_array($parser_file))
{
settype($parser_file, "array");
}
$parser_file[$xml_parser] = $file;
return array($xml_parser, $fp);
}
if (!(list($xml_parser, $fp) = new_xml_parser($file))) {
die("could not open XML input");
}
echo "<pre>";
while ($data = fread($fp, 4096))
{
if (!xml_parse($xml_parser, $data, feof($fp)))
{
die(sprintf("XML error: %s at line %d\n",xml_error_string(xml_get_error_code($xml_parser)), xml_get_current_line_number($xml_parser)));
}
}
echo "</pre>";
echo "parse complete\n";
xml_parser_free($xml_parser);
Re: Reading an XML Post
Posted: Mon Oct 30, 2006 1:09 am
by timvw
kevin7654 wrote:
but how do I tell my scrip it is coming from a post?
Code: Select all
$data = file_get_contents('php://input');
(I don't remember if this also includes the headers, so you might want to chop them off first....)
Posted: Mon Oct 30, 2006 2:17 am
by itsmani1
what exactly is the process of your application? can you please tell me how you are requesting and what is the response type?
Posted: Mon Oct 30, 2006 3:11 am
by volka
You can parse a xml string to a dom with simplexml_load_string().
It doesn't matter where or why this string was created.
Code: Select all
$xml = simplexml_load_string($data);
foreach($xml->Shipment as $shipment) {
echo '<pre>';
echo ' packageId: ', $shipment['PackageID'], "\n",
' Status: ', $shipment['Status'], "\n",
' ShipDate: ', $shipment['ShipDate'], "\n",
' TrackingNumber: ', $shipment['TrackingNumber'], "\n";
foreach($shipment->Item as $item) {
echo ' ItemId: ', $item['ItemID'], "\n";
}
echo "</pre>\n";
}
timvw wrote:Code: Select all
$data = file_get_contents('php://input');
This will provide you the complete request body data. If the xml data is sent without further encoding/methods then this is a good way to get the data.
If the xml input you get is huge you might need a sax parser like itsmani1 has provided. Otherwise I would stick with the much simpler dom.
Now it dependes on exactly how
kevin7654 wrote:My shipping company posts an xml file to my web server.
is done .
Posted: Mon Oct 30, 2006 3:21 am
by itsmani1
volka in my case i am getting data form a file, Here i have question if i am not getting data form the file instead i am getting it as a result of a function call like:
and now my whole xml is in my $data variable how can i fetch data from this variable? I am talking if i use my own code?
Posted: Mon Oct 30, 2006 3:25 am
by volka
Of course. The parser doesn't care where the data comes from. It takes a string of xml data and a flag wether this is the last chunk of data or not.
You can pass the complete data in one go and set
is_final to true.
Code: Select all
xml_parse($xml_parser, $data, true)
Posted: Mon Oct 30, 2006 3:39 am
by itsmani1
thanks man let my try this, one last thing i wanted to know is:
Please see :
http://208.109.22.111/ticketchest/nutest.php
you will see here an xml response.
when i call following code i get this xml
Code: Select all
echo '' . htmlspecialchars($soapclient->response, ENT_QUOTES) . ''
now i wanted to parse this xml but it don't get parse as you will see there is few extra things at the start of it. how can i solve this issue. 2ndly in my file i was getting 4096 data every time in this case if my data is too much how can i Handel this issue.
thanks for the help
Posted: Mon Oct 30, 2006 4:22 am
by volka
Hm, why do you need to parse the "plain" xml from the soap response? It doesn't make much sense to use a soap extension/class if you have to do it all manually by your self anyway.
e.g.
Code: Select all
<?php
$c = new SoapClient('http://www.webservicex.net/geoipservice.asmx?WSDL');
$params = array('IPAddress'=>'88.72.14.195');
$r = $c->__call('GetGeoIP', array($params));
$georesult = $r->GetGeoIPResult;
echo "<pre>\n";
echo $georesult->IP, "\n";
echo $georesult->CountryName, "\n";
echo "</pre>\n";
?>

Maybe a moderator can split this new topic?
Posted: Mon Oct 30, 2006 4:53 am
by itsmani1
volka wrote:Hm, why do you need to parse the "plain" xml from the soap response? It doesn't make much sense to use a soap extension/class if you have to do it all manually by your self anyway.
e.g.
Code: Select all
<?php
$c = new SoapClient('http://www.webservicex.net/geoipservice.asmx?WSDL');
$params = array('IPAddress'=>'88.72.14.195');
$r = $c->__call('GetGeoIP', array($params));
$georesult = $r->GetGeoIPResult;
echo "<pre>\n";
echo $georesult->IP, "\n";
echo $georesult->CountryName, "\n";
echo "</pre>\n";
?>

Maybe a moderator can split this new topic?
every thing with the code you mentioned is fine except
Code: Select all
$georesult = $r->GetGeoIPResult; //How you come to know about this method?
echo "<pre>\n";
echo $georesult->IP, "\n"; //How you come to know about this method?
echo $georesult->CountryName, "\n"; //How you come to know about this method?
In my case how i will come to know about these functions etc and if response values is more than one how i will fetch them?
thanks again
Posted: Mon Oct 30, 2006 6:45 am
by volka
In this case not methods but properties.
I read the wsdl file (only because it's not that complex

)
But php5's soap extension can return the list of functions and types it recognizes from a service description.
Code: Select all
<?php
$c = new SoapClient('http://www.webservicex.net/geoipservice.asmx?WSDL');
echo "<pre>\nfunctions:";
print_r($c->__getFunctions());
echo "</pre>\n";
echo "<pre>\nTypes:";
print_r($c->__getTypes());
echo "</pre>\n";
?>
<pre>
functions:Array
(
[0] => GetGeoIPContextResponse GetGeoIPContext(GetGeoIPContext $parameters)
[1] => GetGeoIPResponse GetGeoIP(GetGeoIP $parameters)
[2] => GeoIP GetGeoIPContext()
[3] => GeoIP GetGeoIP(string $IPAddress)
[4] => GeoIP GetGeoIPContext()
[5] => GeoIP GetGeoIP(string $IPAddress)
)
</pre>
<pre>
Types:Array
(
[0] => struct GetGeoIPContext {
}
[1] => struct GetGeoIPContextResponse {
GeoIP GetGeoIPContextResult;
}
[2] => struct GeoIP {
int ReturnCode;
string IP;
string ReturnCodeDetails;
string CountryName;
string CountryCode;
}
[3] => struct GetGeoIP {
string IPAddress;
}
[4] => struct GetGeoIPResponse {
GeoIP GetGeoIPResult;
}
)
</pre>
nusoap probably provides similar functionality.
Posted: Mon Oct 30, 2006 12:07 pm
by kevin7654
Thanks so much for the responses. Here's the code I am going to try to use:
Code: Select all
$data = file_get_contents('php://input');
$xml = simplexml_load_string($data);
foreach($xml->Shipment as $shipment) {
$body = $body . '<pre>';
$body = $body . ' packageId: ', $shipment['PackageID'], "\n",
' Status: ', $shipment['Status'], "\n",
' ShipDate: ', $shipment['ShipDate'], "\n",
' TrackingNumber: ', $shipment['TrackingNumber'], "\n";
foreach($shipment->Item as $item) {
$body = $body . ' ItemId: ', $item['ItemID'], "\n";
}
$body = $body . "</pre>\n";
}
Unfortunately I don't have much of a way to test it besides just waiting for them to post something. Thanks again for your help.
Kevin
Posted: Mon Oct 30, 2006 11:30 pm
by itsmani1
Code: Select all
$xml = simplexml_load_string($data);
foreach($xml->Shipment as $shipment) {
$body = $body . '<pre>';
$body = $body . ' packageId: ', $shipment['PackageID'], "\n",
' Status: ', $shipment['Status'], "\n",
' ShipDate: ', $shipment['ShipDate'], "\n",
' TrackingNumber: ', $shipment['TrackingNumber'], "\n";
foreach($shipment->Item as $item) {
$body = $body . ' ItemId: ', $item['ItemID'], "\n";
}
Using above code i want to parse data given below given xml output, I tried but it did not worked please help me.
or Please see :
http://208.109.22.111/ticketchest/nutest.php you will see the response in xml formate and debug output where there is an array with the data, please help me if i can parse it.
Code: Select all
HTTP/1.1 200 OK Connection: keep-alive Date: Tue, 31 Oct 2006 05:15:07 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Version: 1.1.4322 Cache-Control: private, max-age=0 Content-Type: text/xml; charset=utf-8 Content-Length: 1193 <?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><GetVenueListResponse xmlns="http://www.eventinventory.com/webservices/"><GetVenueListResult><ROOT xmlns=""><METHODINFO><channelName>Basic View</channelName><methodName>GetVenueList</methodName><parameters>APPCLIENT_ID=2220&EVENT_ID=6&STARTDATE=&INCDAYS=</parameters><processTime type="milliseconds">5.0200</processTime></METHODINFO><DATA xmlns:sql="urn:schemas-microsoft-com:xml-sql"><row THISID="1987" THISNAME="Alliance Theatre" ST="GA" /><row THISID="238" THISNAME="Broward Center Amaturo" ST="FL" /><row THISID="536" THISNAME="Fabulous Fox Theatre - St. Louis" ST="MO" /><row THISID="2233" THISNAME="Ford's Theatre" ST="DC" /><row THISID="657" THISNAME="Goodman Theatre - Albert" ST="IL" /><row THISID="945" THISNAME="Lowell Memorial Auditorium" ST="MA" /><row THISID="1598" THISNAME="Stage Theatre" ST="CO" /><row THISID="2963" THISNAME="Walnut Street Theatre" ST="PA" /></DATA></ROOT></GetVenueListResult></GetVenueListResponse></soap:Body></soap:Envelope>
Posted: Tue Oct 31, 2006 2:44 am
by itsmani1
hay hay hay
i been able to solve the issue till some extent
by using following method i am able get exact xml output;
Code: Select all
echo '<pre>' . htmlspecialchars($soapclient->responseData, ENT_QUOTES) . '</pre>';
final problem is i am using php 4.x.x and it don't support
what could be the solution for it
Posted: Tue Oct 31, 2006 3:23 am
by volka
volka wrote:Hm, why do you need to parse the "plain" xml from the soap response? It doesn't make much sense to use a soap extension/class if you have to do it all manually by your self anyway.