Returning multiple values via SOAP in PHP - php

tl;dr: sending multiple strings as a response to SOAP request.
I am new to SOAP. I have written a simple web service which serves request via SOAP. As I wanted to implement this in PHP, I have used NuSOAP library. The specification given to me for the SOAP API design is as follows.
REQUEST FORMAT:
<?xml version="1.0" encoding="utf-8"?> 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://www.sandeepraju.in/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<soapenv:Body> 
<q0:getData> 
<token>String</token> 
</q0:getData> 
</soapenv:Body> 
</soapenv:Envelope>
EXAMPLE / SAMPLE RESPONSE:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getDataResponse xmlns:ns2="http://www.sandeepraju.in/">
<return>
<Data>
<animal>cat</animal>
<phone>225</phone>
<code>FYI</code>
</Data>
The PHP code I have written for the above specification is as follows.
require_once("../nusoap_old/lib/nusoap.php");
// Definition of getData operation
function getData($token) {
if($token == "somestring") {
return array("animal" => "cat", "phone" => "225", "code" => "FYI");
}
else {
return array("animal" => "null", "phone" => "null", "code" => "null");
}
}
// Creating SOAP server Object
$server = new soap_server();
// Setup WSDL
$server->configureWSDL('catnews', 'urn:catinfo');
$server->wsdl->addComplexType('return_array_php',
'complexType',
'struct',
'all',
'',
array(
'animal' => array('animal' => 'animal', 'type' => 'xsd:string'),
'phone' => array('phone' => 'phone', 'type' => 'xsd:string'),
'code' => array('code' => 'code', 'type' => 'xsd:string')
)
);
// Register the getData operation
$server->register("getData",
array('token' => 'xsd:string'),
array('return' => 'tns:return_array_php'),
'urn:catinfo',
'urn:catinfo#getData');
// Checking POST request headers
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA)? $HTTP_RAW_POST_DATA : "";
$server->service($HTTP_RAW_POST_DATA);
Here, I think I should NOT return a PHP array. But I am not sure what I should return according the specification. Can anyone help me with this. Or returning an array is correct?

You need to add another complex type for an array consisting of your data.
Like this:
$server->wsdl->addComplexType(
'dataArray', // MySoapObjectArray
'complexType', 'array', '', 'SOAP-ENC:Array',
array(),
array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:return_array_php[]')), 'tns:return_array_php'
);
Register the new datatype to be the return-value of the function.
$server->register(
'getData',
array('Datum'=>'xsd:token'),
array('return'=>'tns:dataArray'),
$namespace,
false,
'rpc',
'encoded',
'description'
);
Then your function needs to set the single parts of the array.
function GetData($token)
{
if($token == "somestring") {
$result[0] = array(
"animal" => "cat",
"phone" => "225",
"code" => "FYI"
);
$result[1] = array(
"animal" => "dog",
"phone" => "552",
"code" => "IFY"
);
} else {
$result = null;
}
return $result;
}
The response of this service called with the string "somestring" will be:
<ns1:getDataResponse xmlns:ns1="http://localhost/status/status.php">
<return xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="tns:return_array_php[2]">
<item xsi:type="tns:return_array_php">
<animal xsi:type="xsd:string">cat</animal>
<phone xsi:type="xsd:string">225</phone>
<code xsi:type="xsd:string">FYI</code>
</item>
<item xsi:type="tns:return_array_php">
<animal xsi:type="xsd:string">dog</animal>
<phone xsi:type="xsd:string">552</phone>
<code xsi:type="xsd:string">IFY</code>
</item>
</return>
</ns1:getDataResponse>
That matches your specifications.

Related

Passing xml value as array to soap client PHP

I have xml data to passing to SOAPClient as array
this is my xml data that I want to pass to SOAPClient
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cb5="http://tes.com" xmlns:smar="http://tes.com/Search">
<soapenv:Header />
<soapenv:Body>
<cb5:SmartSearchIndividual>
<cb5:query>
<smar:InquiryReason>Reason</smar:InquiryReason>
<smar:InquiryReasonText />
<smar:Parameters>
<smar:DateOfBirth>1985-05-01</smar:DateOfBirth>
<smar:FullName>J Doe</smar:FullName>
<smar:IdNumbers>
<smar:IdNumberPairIndividual>
<smar:IdNumber>123456789</smar:IdNumber>
<smar:IdNumberType>KTP</smar:IdNumberType>
</smar:IdNumberPairIndividual>
</smar:IdNumbers>
</smar:Parameters>
</cb5:query>
</cb5:SmartSearchIndividual>
</soapenv:Body>
</soapenv:Envelope>
I passing this xml to array like this
$params = array(
'InquiryReason' => 'Reason',
'InquiryReasonText' => '',
'Parameters' => array(
'DateOfBirth' => '1985-05-01',
'FullName' => 'J Doe',
'IdNumbers' => array(
'IdNumberPairIndividual' => array(
'IdNumber' => '123456789',
'IdNumberType' => 'KTP'
)
)
)
);
$response = $client->SmartSearchIndividual($params);
when I submit this show an error The formatter threw an exception while trying to deserialize ....
please help.
thanks!

I call a function with cURL and get a response but when i call the exact same function with soapclient i get a fault

What do I need:
I need some help figuring out an error that i receive from calling a function from a WSDL file with soapclient. Or I would like some help extracting data from a cURL response.
What am I trying to reach:
I am trying to reach to call a function from a WSDL, and get a response from the action.
What are my experiences:
I can call the actions storeOrders succesfull with a cURL statement, I do also get a response.
But with the given response i guess a string. I am not able to extract the data out of it.
So I tried to request the same action from the server but then using soapclient, but I keep getting a error.
What I already tried:
I tried to make the cURL response a new SimpleXMLElement, but it always returns a emty object. Also when I try to reach one of the children.
I tried to make the cURL reponse return as an array and loop trough it with a foreach, also here I got an empty object.
I tried to explode the cURL reponse, but also there i had some problems with the wrong data being returned.
I tried to call it with SoapClient, but I keep getting this error.
So I would like some help with extracting data from cURL, or processing the request with SoapClient.
My cURL request (with answer, all the variables are set with the correct data):
function storeOrderAndGetLabel($delisId, $auth_token, $messageLanguage, $printerLanguage, $paperFormat, $identificationNumber,
$sendingDepot, $product, $mpsCompleteDelivery, $send_name, $send_street, $send_country, $send_zipcode, $send_city,
$send_customerNumber, $rec_name, $rec_street, $rec_state, $rec_country, $rec_zipcode, $rec_city, $parcelLabelNumber,
$orderType)
{
$xml = '
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://dpd.com/common/service/types/Authentication/2.0" xmlns:ns1="http://dpd.com/common/service/types/ShipmentService/3.1">
<soapenv:Header>
<ns:authentication>
<delisId>'.$delisId.'</delisId>
<authToken>'.$auth_token.'</authToken>
<messageLanguage>'.$messageLanguage.'</messageLanguage>
</ns:authentication>
</soapenv:Header>
<soapenv:Body>
<ns1:storeOrders>
<printOptions>
<printerLanguage>'.$printerLanguage.'</printerLanguage>
<paperFormat>'.$paperFormat.'</paperFormat>
</printOptions>
<order>
<generalShipmentData>
<identificationNumber>'.$identificationNumber.'</identificationNumber>
<sendingDepot>'.$sendingDepot.'</sendingDepot>
<product>'.$product.'</product>
<mpsCompleteDelivery>'.$mpsCompleteDelivery.'</mpsCompleteDelivery>
<sender>
<name1>'.$send_name.'</name1>
<street>'.$send_street.'</street>
<country>'.$send_country.'</country>
<zipCode>'.$send_zipcode.'</zipCode>
<city>'.$send_city.'</city>
<customerNumber>'.$send_customerNumber.'</customerNumber>
</sender>
<recipient>
<name1>'.$rec_name.'</name1>
<street>'.$rec_street.'</street>
<state>'.$rec_state.'</state>
<country>'.$rec_country.'</country>
<zipCode>'.$rec_zipcode.'</zipCode>
<city>'.$rec_city.'</city>
</recipient>
</generalShipmentData>
<parcels>
<parcelLabelNumber>'.$parcelLabelNumber.'</parcelLabelNumber>
</parcels>
<productAndServiceData>
<orderType>'.$orderType.'</orderType>
</productAndServiceData>
</order>
</ns1:storeOrders>
</soapenv:Body>
</soapenv:Envelope>
';
$headers = array(
"POST HTTP/1.1",
"Content-type: application/soap+xml; charset=\"utf-8\"",
"SOAPAction: \"http://dpd.com/common/service/ShipmentService/3.1/storeOrders\"",
"Content-length: ".strlen($xml)
);
$cl = curl_init('https://public-ws-stage.dpd.com/services/ShipmentService/V3_1/');
curl_setopt($cl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($cl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($cl, CURLOPT_POST, 1);
curl_setopt($cl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($cl, CURLOPT_POSTFIELDS, "$xml");
curl_setopt($cl, CURLOPT_RETURNTRANSFER, 1);
$output_cl = json_decode(trim(json_encode(curl_exec($cl))), TRUE);
return $output_cl;
//return $output_cl;
}
And from this code i get the reponse, i guess it is a string but i don't know for sure:
<soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:body>
<ns2:storeordersresponse xmlns:ns2="http://dpd.com/common/service/types/ShipmentService/3.1">
<orderresult>
<parcellabelspdf>pdfkey</parcellabelspdf>
<shipmentresponses>
<identificationnumber>identificationnumber</identificationnumber>
<mpsid>mpsid</mpsid>
<parcelinformation>
<parcellabelnumber>labelnr</parcellabelnumber>
</parcelinformation>
</shipmentresponses>
</orderresult>
</ns2:storeordersresponse>
</soap:body>
</soap:envelope>
Now my function calling the SoapClient function:
$label = storeOrderAndGetLabel($delisId, $auth_token, $messageLanguage, $printerLanguage, $paperFormat, $identificationNumber,
$sedingDepot, $product, $mpsCompleteDelivery, $send_name, $send_street, $send_country, $send_zipcode, $send_city,
$send_customerNumber, $rec_name, $rec_street, $rec_state, $rec_country, $rec_zipcode, $rec_city, $parcelLabelNumber,
$orderType);
print_r($label);
now the soap call itself:
function storeOrderAndGetLabel($delisId, $auth_token, $messageLanguage, $printerLanguage, $paperFormat, $identificationNumber,
$sendingDepot, $product, $mpsCompleteDelivery, $send_name, $send_street, $send_country, $send_zipcode, $send_city,
$send_customerNumber, $rec_name, $rec_street, $rec_state, $rec_country, $rec_zipcode, $rec_city, $parcelLabelNumber,
$orderType)
{
$client = new SoapClient('https://public-ws-stage.dpd.com/services/ShipmentService/V3_1?WSDL');
$label = $client->storeOrders
(array
(
"printOptions" => array
(
"printerLanguage" => "$printerLanguage",
"paperFormat" => "$paperFormat"
),
"order" => array
(
"generalShipmentData" => array
(
"identificationNumber" => "$identificationNumber",
"sendingDepot" => "$sendingDepot",
"product" => "$product",
"mpsCompleteDelivery" => "$mpsCompleteDelivery",
"sender" => array
(
"name1" => "$send_name",
"street" => "$send_street",
"country" => "$send_country",
"zipCode" => "$send_zipcode",
"city" => "$send_city",
"customerNumber" => "$send_customerNumber"
),
"recipient" => array
(
"name1" => "$rec_name",
"street" => "$rec_street",
"state" => "$rec_state",
"country" => "$rec_country",
"zipCode" => "$rec_zipcode",
"city" => "$rec_city"
)
),
"parcels" => array
(
"parcelLabelNumber" => "$parcelLabelNumber"
),
"productAndServiceData" => array
(
"orderType" => "$orderType"
)
)
)
);
return $label;
}
The error I receive from the soapcall:
Fatal error: Uncaught SoapFault exception: [soap:Server] Fault occurred while processing. in getLabel.php:107 Stack trace: #0 getLabel.php(107): SoapClient->__call('storeOrders', Array) #1 getLabel.php(107): SoapClient->storeOrders(Array) #2 getLabel.php(38): storeOrderAndGetLabel('username', 'password...', 'nl_NL', 'PDF', 'A4', '77777', '0163', 'CL', '0', 'uname', 'straat', 'NL', 'zipcode', 'City', '341546246451...', 'Test-Empfaenger', 'Test-Strasse', 'BY', 'DE', '123451', 'ahahaha', '16231545', 'consignment') #3 {main} thrown in getLabel.php on line 107
I would like to extract the parcellabelspdf key and the mpsid from the response. It would be really nice if someone could take a look at it.
Two possible problems:
You need to authenticate when calling the DPD ShipmentService. See below for a working example.
Make sure, that the parameter mpsCompleteDelivery is passed as an integer (0), not the string "false". Consider changing this line:
"mpsCompleteDelivery" => "$mpsCompleteDelivery"
to:
"mpsCompleteDelivery" => $mpsCompleteDelivery
Here is a full example including the login and output of a DPD-label as PDF:
// Let's log in first...
$c = new SoapClient('https://public-ws-stage.dpd.com/services/LoginService/V2_0?wsdl');
$res = $c->getAuth(array(
'delisId' => 'your-Id',
'password' => 'your-Password',
'messageLanguage' => 'de_DE'
));
// ...and remember the token.
$auth = $res->return;
// ...and then generate a label
$c = new SoapClient('https://public-ws-stage.dpd.com/services/ShipmentService/V3_1?wsdl');
$token = array(
'delisId' => $auth->delisId,
'authToken' => $auth->authToken,
'messageLanguage' => 'de_DE'
);
// Set the header with the authentication token
$header = new SOAPHeader('http://dpd.com/common/service/types/Authentication/2.0', 'authentication', $token);
$c->__setSoapHeaders($header);
try {
$res = $c->storeOrders( array
(
"printOptions" => array(
"paperFormat" => "A4",
"printerLanguage" => "PDF"
),
"order" => array(
"generalShipmentData" => array(
"sendingDepot" => $auth->depot,
"product" => "CL",
"mpsCompleteDelivery" => false,
"sender" => array(
"name1" => "Sender Name",
"street" => "Sender Street 2",
"country" => "DE",
"zipCode" => "65189",
"city" => "Wiesbaden",
"customerNumber" => "123456789"
),
"recipient" => array(
"name1" => "John Malone",
"street" => "Johns Street 34",
"country" => "DE",
"zipCode" => "65201",
"city" => "Wiesbaden"
)
),
"parcels" => array(
"parcelLabelNumber" => "09123829120"
),
"productAndServiceData" => array(
"orderType" => "consignment"
)
)
)
);
} catch (SoapFault $exception) {
echo $exception->getMessage();
die();
}
// Et voilà!
header('Content-type: application/pdf');
echo $res->orderResult->parcellabelsPDF;
Check here for more information:
http://labor.99grad.de/2014/10/05/deutscher-paket-dienst-dpd-soap-schnittstelle-mit-php-nutzen-um-versandetikett-als-pdf-zu-generieren/

NuSoap returns complexType array not correct?

I have a Webservice WSDL with NuSoap. I use it with CodeIgniter. I have problems with contexttype-array returns. Here is my PHP Code:
$this->nusoap_server->wsdl->addComplexType(
"getJobStatusByIdsResponse",
"complexType",
"array",
"all",
"SOAP-ENC:Array",
array(),
array(
'Job' => array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:jobStatusResponse[]', 'minOccurs'=>'1', 'maxOccurs'=>'unbounded')
),
'tns:jobStatusResponse'
);
$this->nusoap_server->wsdl->addComplexType(
"getJobStatusByIdsResponse",
"complexType",
"array",
"all",
"SOAP-ENC:Array",
array(),
array(
'Job' => array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:jobStatusResponse[]', 'minOccurs'=>'1', 'maxOccurs'=>'unbounded')
),
'tns:jobStatusResponse'
);
$this->nusoap_server->register(
"getJobStatusByIds",
array('getJobStatusByIdsRequest' => 'tns:getJobStatusByIdsRequest'),
array('getJobStatusByIdsResponse' => 'tns:getJobStatusByIdsResponse'),
false,
false,
"rpc",
"literal",
"get JobStatus By Ids"
);
function getJobStatusByIds($data) {
return array(array('orderId' => '1000', 'jobStatus' => '5'),array('orderId' => '1001', 'jobStatus' => '3'),array('orderId' => '1002', 'jobStatus' => '7'))
}
I get this as return:
<ns1:getJobStatusByIdsResponse xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/">
<getJobStatusByIdsResponse>
<item>
<orderId>1001</orderId>
<jobStatus>5</jobStatus>
</item>
<item>
<orderId>1002</orderId>
<jobStatus>3</jobStatus>
</item>
<item>
<orderId>1003</orderId>
<jobStatus>7</jobStatus>
</item>
</getJobStatusByIdsResponse>
</ns1:getJobStatusByIdsResponse>
That not right, isn't it?
How can i get it like this ('Job' instead of 'item'):
<ns1:getJobStatusByIdsResponse xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/">
<getJobStatusByIdsResponse>
<Job>
<orderId>1001</orderId>
<jobStatus>5</jobStatus>
</Job>
<Job>
<orderId>1002</orderId>
<jobStatus>3</jobStatus>
</Job>
<Job>
<orderId>1003</orderId>
<jobStatus>7</jobStatus>
</Job>
</getJobStatusByIdsResponse>
</ns1:getJobStatusByIdsResponse>
Who can me help?
Where can I find more examples for NuSoap?
Hope this helps.
Added the code comments to help for those that have trouble remembering the NuSoap params off hand.
$this->nusoap_server->register(
"getJobStatusByIds", // method name
array('getJobStatusByIdsRequest' => 'tns:getJobStatusByIdsRequest'), // input params
array('getJobStatusByIdsResponse' => 'tns:getJobStatusByIdsResponse'), // output params
false, // namespace
false, // soap action
"rpc", // style
"literal", // use
"get JobStatus By Ids" // documentation
);
I think the response the definition should look something like this.
// Job Status Result Complex Type (output)
$this->nusoap_server->wsdl->addComplexType(
"getJobStatusByIdsResponse",
"complexType",
"struct",
"all",
"SOAP-ENC:Array",
array('Job' => array('orderId' => 'your value here', jobStatus => 'your value here')),
);

How can i set attributes with NuSoap in PHP?

I am working with nuSoap to build a soap server.
But i cant get the attributes the way i want.
I would like as return value:
<return xsi:type="tns:Taxatie">
<EmailAdres OptIn="1" xsi:type="tns:string">email#domain.com</EmailAdres>
</return>
And i get:
<return xsi:type="tns:Taxatie">
<EmailAdres OptIn="1" xsi:type="tns:EmailAdres">
<EmailAdres xsi:type="xsd:string">email#domain.com</EmailAdres>
</EmailAdres>
</return>
anyone know what i must change?
Or how I should set up the arrays?
This is my test code:
<?php
require_once("nusoap.php");
$soapserver = new nusoap_server();
$soapserver->configureWSDL('thijs.test', 'urn:thijs.test');
$soapserver->wsdl->addComplexType(
'Taxatie',
'complexType',
'struct',
'all',
'',
array(
'EmailAdres' => array('name' => 'EmailAdres', 'type' => 'tns:EmailAdres')
)
);
$soapserver->wsdl->addComplexType(
'EmailAdres',
'simpleType',
'struct',
'all',
'',
array(
"EmailAdres" => array('name' => 'EmailAdres', 'type' => 'xsd:string', 'minOccurs' => 0)
),
array(
'OptIn' => array('name' => 'OptIn', 'type' => 'xsd:boolean', 'use' => 'required')
)
);
$soapserver->register('taxatie', // method name
array(), // input parameters
array('return' => 'tns:Taxatie'), // output parameters
'urn:thijs.test', // namespace
'urn:thijs.test#taxatie', // soapaction
'rpc', // style
'encoded', // use
'return something' // documentation
);
class taxatie
{
var $EmailAdres = null;
function taxatie()
{
$this->EmailAdres = new emailadres();
}
}
class emailadres
{
var $EmailAdres = 'email#domain.com';
var $OptIn = true;
}
function taxatie()
{
return new taxatie();
}
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$soapserver->service($HTTP_RAW_POST_DATA);
Thanks in advance
Why not simply return an array instead of using complex type?
e.g
$resultarray['taxatie'] = array(
'EmailAdres' => $row["EmailAdres"],
'tagcount' => $row["tagcount"],
'OptIn' => $row["OptIn"]
);

Nusoap - fix empty xmlns attribute for the response

i have created a simple web service using Php Nusoap. its working correctly but the only thing missing is to add the default xmlns attribute to the response tag.
Here is the copy of Response :
<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 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>
<LoginResponse xmlns="">
<LoginResult>
<register>
<customer>d2ff3b88d34705e01d150c21fa7bde07</customer>
</register>
</LoginResult>
</LoginResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Here is the code :
<?php
require_once ('nusoap.php');
// set namespace
$ns = 'mynamspace';
// set up soap server
$server = new soap_server ();
$server->configureWSDL ( 'testservice', $ns);
$server->wsdl->schemaTargetNamespace = $ns;
// define new user data type
// define results
$server->wsdl->addComplexType ( 'customer', 'complexType', 'struct', '', '', array ('customer' => array ('name' => 'customer', 'type' => 'xsd:string' ) ) );
$server->wsdl->addComplexType ( 'register', 'complexType', 'struct', '', '', array ('register' => array ('name' => 'register', 'type' => 'tns:customer' ) ) );
$server->wsdl->addComplexType ( 'LoginResult', 'complexType', 'struct', '', '', array ('LoginResult' => array ('name' => 'LoginResult', 'type' => 'tns:register' ) ) );
// register Login function
$server->register ( 'Login', // method name
array ('username' => 'xsd:string', 'password' => 'xsd:string' ), // input parameters
array ('LoginResult' => 'tns:register' ), // output parameters
'urn:mynamespace', // namespace
'urn:mynamespaceAction', // soapaction
'document', // style
'literal', // use
'Login service for testing' ); // documentation
function Login($username, $password) {
if (isset ( $username ) && isset ( $password )) {
$hash = md5 ( $username );
return array ('LoginResult' => array ('register' => array ('customer' => $hash ) ));
}
}
// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset ( $HTTP_RAW_POST_DATA ) ? $HTTP_RAW_POST_DATA : '';
$server->service ( $HTTP_RAW_POST_DATA );
?>
Any help is greatly appreciated.
I don't claim this is particularly elegant, but worked in my case:
I went into the nusoap.php and commented this line (line 5925 for me):
//$elementNS = " xmlns=\"\"";
directly after this:
if ($unqualified && $use == 'literal') {

Categories