Php Nusoap fails with latin characters - php

I am developing a webservice using Nusoap to send xml data, and this time I have to send data with latin characters like 'ó'. However when I put it in the soap client it stops working. Below is a summary of code being develped to test sending xml with latin characters.
This is ths summary of server code being developed:
include_once("nusoap/nusoap.php");
$server = new soap_server();
$server->configureWSDL("PersonImport","urn:PersonImport");
$server->register("PersonImport",array("login" => "xsd:string", 'senha' => 'xsd:string', 'fornecedor' => 'xsd:string'),array("return" => "xsd:string"),"urn:PersonImport","urn:PersonImport#PersonImport");
function PersonImport($login,$senha,$fornecedor) {
//Just for debug purposes
$return = "My login Is <b>".$login . "</b> And My senha Is <b>".$senha."</b> And My fornecedor Is <b>".$fornecedor."</b>.";
(...)(ommited code, xml parsing and response xml generation)
return $return;
}
This is ths summary of client code:
<?php
require_once("nusoap/nusoap.php");
$client = new soapclient("example.com?wsdl");
$xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>";
$xml .= "<fornecedor>";
$xml .= "<NAME1>Gian</NAME1>";
$xml .= "<MCOD1>Giancarlo SA</MCOD1>";
$xml .= "<STCD1>80048303000113</STCD1>";
$xml .= "<STCD2>55670185501</STCD2>";
$xml .= "<STCD3>5508150087</STCD3>";
$xml .= "<RG>359730553</RG>";
$xml .= "<STRAS>rua itororó</STRAS>";
$xml .= "<HOUSE_NUM1>81</HOUSE_NUM1>";
$xml .= "<HOUSE_NUM2>301</HOUSE_NUM2>";
$xml .= "<ORT02>Menino Deus</ORT02>";
$xml .= "<PSTLZ>90110290</PSTLZ>";
$xml .= "<REGIO>RS</REGIO>";
$xml .= "<ORT01>Porto Alegre</ORT01>";
$xml .= "<TELF1>32335675</TELF1>";
$xml .= "<TELFX>32335675</TELFX>";
$xml .= "<SMTP_ADDR>teste#teste.com</SMTP_ADDR>";
$xml .= "<ERDAT>2016-10-04</ERDAT>";
$xml .= "<ChangeData>2016-10-04</ChangeData>";
$xml .= "<StartData>2016-10-04</StartData>";
$xml .= "<OffData>2016-10-04</OffData>";
$xml .= "</fornecedor>";
$result = $client->PersonImport("login","password", $xml);
echo $result;
The line
$xml .= "<STRAS>rua itororó</STRAS>";
has a special character. If I remove the 'ó' character it works.
I tried to set encoding on xml:
$xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>";
This worked for me when I had to parse xml with SimpleXML Parser, but it didn't work on soap.
I tried to set header of the page for utf8 or ISO-8859-1 like this:
header("Content-type:text/html; charset=UTF-8");
or:
header ('Content-type: text/html; charset=ISO-8859-1');
I tried to use htmlentities, but the entity for 'ó' is '& o a c u t e;' which has the special character '&' and then the same problem happens.
function serialize didn't resolve the problem.
I couldn't find an answer until now on google.
Is it possible to pass latin special characters using nusoap? There must be a way.

Looks like I found a way. Using CDATA I can escape the '&', so I can use htmlentities on strings, like this:
$xml .= "<STRAS><![CDATA[".htmlentities("Rua Itororó")."]]></STRAS>";

Related

Creating an XML file from PHP

I am trying to create XML files via PHP for Googles Merchant center.
I had previously done the same with creating a sitemap but now am having issues.
$xmlString = '<?xml version="1.0" encoding="UTF-8"?>';
$xmlString .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">';
$xmlString .= '<url>';
$xmlString .= '<loc>example.com</loc>';
$xmlString .= '<lastmod>'.date(DATE_ATOM,time()).'</lastmod>';
$xmlString .= '<changefreq>daily</changefreq>';
$xmlString .= '<priority>1.0</priority>';
$xmlString .= '</url>';
$xmlString .= '</urlset>';
$dom = new DOMDocument;
$dom->preserveWhiteSpace = FALSE;
$dom->loadXML($xmlString);
$dom->save('../sitemap.xml');
This is more or less what I have to create my sitemap except I am obviously creating more URLs by querying my database.
But then I do more or less the exact same thing for my product feed but it does not work.
$xmlString .= '<?xml version="1.0" encoding="UTF-8"?>';
$xmlString .= '<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">';
$xmlString .= '<channel>';
$xmlString .= '<title>Product Feed</title>';
$xmlString .= '<link>https://www.example.com/</link>';
$xmlString .= '<description>Product Feed</description>';
$xmlString .= '<item>';
$xmlString .= '<g:id>'.$product_id.'</g:id>';
$xmlString .= '<title>'.$product_name.'</title>';
$xmlString .= '<description>'.$product_description.'</description>';
$xmlString .= '<link>https://www.example.com/product/'.$product_url.'</link>';
$xmlString .= '<g:condition>new</g:condition>';
$xmlString .= '<g:price>'.$rounded_lowest_sale_price.'</g:price>';
$xmlString .= '<g:availability>in stock</g:availability>';
$xmlString .= '<g:image_link>https://www.example.com/media/product_images/'.$first_image.'</g:image_link>';
$xmlString .= '<g:mpn>'.$model_no.'</g:mpn>';
$xmlString .= '<g:brand>'.$brand.'</g:brand>';
$xmlString .= '<g:google_product_category>Business & Industrial > Material Handling</g:google_product_category>';
$xmlString .= '</item>';
}
$xmlString .= '</channel>';
$xmlString .= '</rss>';
echo $xmlString;
$dom = new DOMDocument;
$dom->preserveWhiteSpace = FALSE;
$dom->loadXML($xmlString);
$dom->save('../product_feeds/product_feed_int.xml');
It saves the XML file but all it contains is:
<?xml version="1.0"?>
without even the UTF-8 encoding.
If you don't use DOMDocument to create the xml you can put your string directly into a file
file_put_contents('../product_feeds/product_feed_int.xml', $xmlString);
consider to use & for & in
Business & Industrial
This might Help
<?php
$xmldoc = new DOMDocument();
$xmldoc->encoding = 'utf-8';
$xmldoc->xmlVersion = '1.0';
$xmldoc->formatOutput = true;
$xml_file_name = 'xmlfile.xml';
$root = $xmldoc->createElement('Cars');
$car_node = $xmldoc->createElement('car');
$attr_movie_id = new DOMAttr('car_model', 'ritz');
$car_node->setAttributeNode($attr_movie_id);
$child_node_title = $xmldoc->createElement('Make', 'Maruti');
$car_node->appendChild($child_node_title);
$child_node_year = $xmldoc->createElement('Year', 2012);
$car_node->appendChild($child_node_year);
$child_node_genre = $xmldoc->createElement('Type', 'Hatchback');
$car_node->appendChild($child_node_genre);
$child_node_ratings = $xmldoc->createElement('Ratings', 6.2);
$car_node->appendChild($child_node_ratings);
$root->appendChild($car_node);
$xmldoc->appendChild($root);
$xmldoc->save($xml_file_name);
echo "$xml_file_name created";
?>

how to do linebreaks in XML?

I finally got my xml-(pre-)parsing-script ready. It parses and checks each element, and saves a amount of elements to a new xml-file.
My "problem" is that in the new xml-file all is written unformatted and without linebreaks.
while ($xml = $chunk->read()) {
$obj = simplexml_load_string($xml);
// check if ID is in Array
if(!in_array((string)$obj->id, $ids)) {
$chunkCount++;
$xmlData .= '<product>';
foreach($obj as $key => $value) {
$xmlData .= '<'.$key.'>'.$value.'</'.$key.'>';
}
$xmlData .= '</product>\n';
// if $chunkLimit is reached, save to file
if($chunkCount == $chunkLimit) {
$xp = fopen($file = "slices/slice_".$sliceCount.".xml", "w");
fwrite($xp, '<?xml version="1.0" ?>'."");
fwrite($xp, "<item>");
fwrite($xp, $xmlData);
fwrite($xp, "</item>");
fclose($xp);
print "Written ".$file."<br>";
$xmlData = '';
$chunkCount = 0;
$sliceCount++;
}
}
}
How could I get my xml-slices look good, with linebreaks? .. I already tried \nbut it simply writes \n to the new file.
The trick is to use " instead of ' for special characters to be parsed as special.
so
$xmlData .= '</product>\n';
should be
$xmlData .= "</product>\n";
You can also use \t for tabs, if you want indentation!
Use special chars \n and \t for tabulations.
So:
fwrite($xp, "<item>\n");
fwrite($xp, "\t" . $xmlData."\n");
fwrite($xp, "</item>\n");

Converting a returned PHP file to XML

I am looking for a way to convert a PHP file that I retrieve from a website into XML format using a PHP script.
The returned file I get is:
{ "days": [
{"reference":"13L6-A67-1", "dayinit":"4","hourinit":"9"},
{"reference":"13L6-A67-1", "dayinit":"5","hourinit":"9"} ]}
Is there anyway I could convert this to an XML file like this:
<?xml version="1.0"?>
<days>
<day>
<lesson>
<reference>13L6-A67-1</reference>
<hourinit>9</hourinit>
</lesson>
</day>
<day>
<lesson>
<reference>13L6-A67-1</reference>
<hourinit>9</hourinit>
</lesson>
</day>
</days>
Preferably so it groups data based on the "dayinit".
You can convert the data to an array and loop through it:
$test_array = json_decode('{ "days": [
{"reference":"13L6-A67-1", "dayinit":"4","hourinit":"9"},
{"reference":"13L6-A67-1", "dayinit":"5","hourinit":"9"} ]}',true);
$xml = '<?xml version="1.0"?>';
$xml .= '<days>';
foreach($test_array['days'] as $day) {
$xml .= '<day>';
$xml .= '<lesson>';
$xml .= '<reference>';
$xml .= $day['reference'];
$xml .= '</reference>';
$xml .= '<dayinit>';
$xml .= $day['reference'];
$xml .= '</reference>';
$xml .= '</dayinit>';
$xml .= $day['hourinit'];
$xml .= '</hourinit>';
$xml .= '</lesson>';
$xml .= '</day>';
}
$xml .= '</days>';
What you retrieve is content written in JSON. You could try to use PHP native functions to transform your content. The following example is rough draw how you could approach your solution.
First, fetch and decode JSON (documentation):
$json = '...'; // JSON content
$data = json_decode($json, true);
Then, use the XML Parser (documentation) to render your $data into XML:
// Something like
$xml_parser = xml_parser_create();
xml_parse($xml_parser, $data);

how to compress a sitemap with php

I have this below code and it work fine
header ("content-type: text/xml");
$xml = '<?xml version="1.0" encoding="UTF-8"?>';
$xml .= '<urlset xmlns="http://www.google.com/schemas/sitepam/0.84">';
$xml .= '<url><loc>'.SiteRoot.'</loc><changefreq>daily</changefreq><priority>1.0</priority></url>';
$xml .= '<url><loc>'.SiteRoot.'/directory</loc><changefreq>daily</changefreq><priority>0.9</priority></url>';
$Query = mysql_query ("SELECT link FROM `om` ORDER BY `link`");
while($row = mysql_fetch_array($Query)) {
$xml .= '<url>';
$xml .= '<loc>'.GenerateLink( 'link',$row['link'] ).'</loc>';
$xml .= '<changefreq>weekly</changefreq>';
$xml .= '<priority>0.8</priority>';
$xml .= '</url>';
}
$xml .= '</urlset>';
echo $xml;
When i try to compress it with mime header
header('content-type: application/x-gzip');
header('Content-Disposition: attachment; filename="sitemap.xml.gz"');
Browser download a .gz file but it's not open. winrar give me a error that said: The archive is either in unknown format or damaged
This is the final code :
// header ("content-type: text/xml");
header('content-type: application/x-gzip');
header('Content-Disposition: attachment; filename="sitemap.xml.gz"');
$xml = '<?xml version="1.0" encoding="UTF-8"?>';
$xml .= '<urlset xmlns="http://www.google.com/schemas/sitepam/0.84">';
$xml .= '<url><loc>'.SiteRoot.'</loc><changefreq>daily</changefreq><priority>1.0</priority></url>';
$xml .= '<url><loc>'.SiteRoot.'/directory</loc><changefreq>daily</changefreq><priority>0.9</priority></url>';
$Query = mysql_query ("SELECT link FROM `om` ORDER BY `link`");
while($row = mysql_fetch_array($Query)) {
$xml .= '<url>';
$xml .= '<loc>'.GenerateLink( 'link',$row['link'] ).'</loc>';
$xml .= '<changefreq>weekly</changefreq>';
$xml .= '<priority>0.8</priority>';
$xml .= '</url>';
}
$xml .= '</urlset>';
echo $xml;
Try using some of the built in gzip functions like gzencode
echo gzencode($xml);

XML source generated by PHP is messy [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
format xml string
I'm generating an XML page like so:
header('Content-Type: text/html');
$xmlpage = '<?xml version="1.0" charset="utf-8"?>';
$xmlpage .= '<conv>';
$xmlpage .= '<at>6 January 2012 12:00</at>';
$xmlpage .= '<rate>1.56317</rate>';
$xmlpage .= '<from>';
$xmlpage .= '<code>'.$from.'</code>';
$xmlpage .= '<curr>Pound Sterling</curr>';
$xmlpage .= '<loc>UK</loc>';
$xmlpage .= '<amnt>'.$amnt.'</amnt>';
$xmlpage .= '</from>';
$xmlpage .= '</conv>';
echo $xmlpage;
When viewing the page source, it looks terrible:
<?xml version="1.0" charset="utf-8"?><conv><at>6 January 2012 12:00</at><rate>1.56317</rate><from><code>USD</code><curr>Pound Sterling</curr><loc>UK</loc><amnt>23</amnt></from><to><code>GBP</code><curr>United States Dollar</curr><loc>USA</loc><amnt>14.73</amnt></to></conv>
How can I make this so it's properly formatted and indented?
Add newlines with the \r\n or only \n characters. You'll need to place your strings in double quotes ("") for it to work, so either replace the double-quotes inside the strings with single ones ('), escape the double quotes (\"), add ."\r\n" as a linebreak or use HEREDOC.
Building your XML with a XML generator like the built-in SimpleXML will prevent these sort and numerous other types of problems and is usually far easier than building it by hand with strings.
You could:
Do it yourself by adding whitespace characters to your strings (\n, \t).
Output all your XML with a HEREDOC
You could create or even generate a DOMDocument and use saveXML()
The first two are quick and dirty (heredoc's better). The latter is more robust, but more code.
Use a HEREDOC. it'll be far easier to read than repeated string concatenation, allows tabs/multilines, and does variable interpolation for you:
$xmlpage = <<<EOL
<?xml version="1.0" charset="utf-8"?>
<conv>
<at>6 January 2012 12:00</at>
<rate>1.56317</rate>
<from>
<code>$from</code>
<curr>Pound Sterling</curr>
<loc>UK</loc>
<amnt>$amnt</amnt>
</from>
</conv>
EOL;
Use a stylesheet and an XML viewer to view it.
add a \n after every $xmlpage. You should be able to view it properly after the echo.
e.g.
$xmlpage = "<?xml version="1.0" charset="utf-8"?>\n";
$xmlpage .= "<conv>\n";
$xmlpage .= "<at>6 January 2012 12:00</at>\n";
$xmlpage .= "<rate>1.56317</rate>\n";
The simplest way would be to add the appropriate whitespace to the beginning of the strings, and the newlines to the ends.
$xmlpage = '<?xml version="1.0" charset="utf-8"?>';
$xmlpage .= '<conv>' . "\n";
$xmlpage .= "\t" . '<at>6 January 2012 12:00</at>' . "\n";
$xmlpage .= "\t" . '<rate>1.56317</rate>' . "\n";
$xmlpage .= '<from>' . "\n";
$xmlpage .= "\t" . '<code>'.$from.'</code>' . "\n";
$xmlpage .= "\t" . '<curr>Pound Sterling</curr>' . "\n";
$xmlpage .= "\t" . '<loc>UK</loc>' . "\n";
$xmlpage .= "\t" . '<amnt>'.$amnt.'</amnt>' . "\n";
$xmlpage .= '</from>' . "\n";
$xmlpage .= '</conv>';
Or something along those lines, depending on your desired output.
Here's my prettify function, which formats for output. You can modify it to suit your needs.
function prettifyXML( $xml )
{
// Break our XML up into sections of newlines.
$xml = preg_replace( '/(<[^\/][^>]*?[^\/]>)/', "\n" . '\1', $xml );
$xml = preg_replace( '/(<\/[^\/>]*>|<[^\/>]*?\/>)/', '\1' . "\n", $xml );
$xml = str_replace( "\n\n", "\n", $xml );
$xml_chunks = explode( "\n", $xml );
$indent_depth = 0;
$open_tag_regex = '/<[^\/\?][^>]*>/';
$close_tag_regex = '/(<\/[^>]*>|<[^>]*\/>)/';
// Fix the indenting.
foreach ( $xml_chunks as $index => $xml_chunk )
{
$close_tag_count = preg_match( $close_tag_regex, $xml_chunk );
$open_tag_count = preg_match( $open_tag_regex, $xml_chunk );
if ( $open_tag_count >= $close_tag_count )
{
$temp_indent_depth = $indent_depth;
}
else
{
$temp_indent_depth = $indent_depth - $close_tag_count;
}
$xml_chunks[ $index ] = str_repeat( "\t", $temp_indent_depth ) . $xml_chunk;
$indent_depth += $open_tag_count - $close_tag_count;
}
$xml = implode( "\n", $xml_chunks );
// Add tokens for attributes and values.
$attribute_regex = '/([\w:]+\="[^"]*")/';
$value_regex = '/>([^<]*)</';
$value_span_token = '########';
$attribute_span_token = '########';
$span_close_token = '########';
$xml = preg_replace( $value_regex, '>' . $value_span_token . '\1' . $span_close_token . '<', $xml );
$xml = preg_replace( $attribute_regex, $attribute_span_token . '\1' .$span_close_token, $xml );
$xml = htmlentities( $xml );
// Replace the tokens that we added previously with their HTML counterparts.
$xml = str_replace( $value_span_token, '<span class="value">', $xml );
$xml = str_replace( $attribute_span_token, '<span class="attribute">', $xml );
$xml = str_replace( $span_close_token, '</span>', $xml );
return $xml;
}
It's been relatively well tested to handle edge cases, though it's not highly efficient because it's only for viewing logs.

Categories