how to dynamically change the value of an xml node with php - php

<?xml version="1.0" encoding="UTF-8" ?>
<SMS>
<authentification>
<username>xxxx</username>
<password>xxxx</password>
</authentification>
<recipients>
<number>8309042932</number>
</recipients>
</SMS>
my number node has a dynamically generated numbers for different people, i want to load all the numbers, but am getting only the last number.
Code used to create the xml string:
<?xml version="1.0" encoding="UTF-8" ?>
$xmlstring =
"<SMS>
<authentification>
<username>xxxx</username>
<password>xxxx</password>
</authentification>
<recipients>";
foreach($gsmnumbers as $number) {
$number = explode(",", $number);
foreach($number as $num) {
$count = count($num);
for($i = 0; $i < $count; $i++) {
$xmlHalf = "<gsm>$num</gsm>";
}
}
}
$xmlSecondHalf = "</recipients> </SMS>";

Try this, all sorts of mistakes in your code.
Basically if you use the .= syntax, you can concatenate to the end of an existing string where just using = will replace the string with the new value.
Also the <?xml version="1.0" encoding="UTF-8" ?> need to be in the string to identify it as a valid XML string.
$xmlstring = '
<?xml version="1.0" encoding="UTF-8" ?>
<SMS>
<authentification>
<username>xxxx</username>
<password>xxxx</password>
</authentification>
<recipients>';
foreach($gsmnumbers as $number) {
$nums = explode(",", $number);
foreach($nums as $num) {
$xmlstring .= "<gsm>$num</gsm>";
}
}
$xmlstring .= "</recipients></SMS>";

Don't write XML as string, use a XML library for that. A library normally prevents you from shooting into your own foot when it comes to creating XML. It also makes your code more readable. Example:
// process and transform input data
$gsmnumbers = ['1234,5678,9012'];
$gsms = [];
foreach ($gsmnumbers as $number) {
$nums = explode(",", $number);
foreach ($nums as $num) {
$gsms[] = $num;
}
}
// create XML
$request = new SimpleXMLElement('<SMS/>');
$authentication = $request->addChild('authentification');
$authentication->username = 'XXXX';
$authentication->password = 'XXXX';
$recipients = $request->addChild('recipients');
foreach ($gsms as $gsm) {
$recipients->addChild('gsm', $gsm);
}
echo $request->asXML();
Example output:
<?xml version="1.0"?>
<SMS><authentification><username>XXXX</username><password>XXXX</password></authentification><recipients><gsm>1234</gsm><gsm>5678</gsm><gsm>9012</gsm></recipients></SMS>

Related

USing php xml generation of specific format

Hi i want to create a php code which generates xml of specific format given below. Kindly help me through this
<?xml version="1.0" encoding="utf-8"?>
<order>
<requisition>
<dateofservice>2012-12-13</dateofservice>
<labid>str1234</labid>
<reqnotes_c>str1234</reqnotes_c>
<rptemail_c>str1234</rptemail_c>
<rptmethod_c>str1234</rptmethod_c>
<specimen_type_c>str1234</specimen_type_c>
<collectiontype_c>str1234</collectiontype_c>
</requisition>
<patient>
<firstname>str1234</firstname>
<lastname>str1234</lastname>
<dob>2012-12-13</dob>
<breed_c>str1234</breed_c>
<species>str1234</species>
<sex>s</sex>
<sterilization_c>str1234</sterilization_c>
</patient>
</order>
My code is this Now correct me please. My code gives only one parent and i want to generate the output as given above
while (($row = fgetcsv($inputFile)) !== FALSE){
$container = $doc->createElement('row');
foreach($headers as $i => $header) {
if(!empty($row[$i])) {
$child = $doc->createElement($header);
$child = $container->appendChild($child);
$value = $doc->createTextNode($row[$i]);
$value = $child->appendChild($value);
}
}
$root->appendChild($container);
}
$strxml = $doc->saveXML();

XML parsing only some nodes - PHP

I have the following example XML:
<PRODUCTRATINGLIST>
<PRODUCT>
<VENDORREF>AC308A~</VENDORREF>
<RATING>100%</RATING>
<REVIEWCOUNT>7</REVIEWCOUNT>
</PRODUCT>
<PRODUCT>
<VENDORREF>AC308C~</VENDORREF>
<RATING>98%</RATING>
<REVIEWCOUNT>89</REVIEWCOUNT>
</PRODUCT>
</PRODUCTRATINGLIST>
I'm simply trying to extract each node under PRODUCT:
$ratings = simplexml_load_file("test.xml");
foreach ($ratings->PRODUCT as $rating){
$part = $rating->VENDORREF;
$rating = str_replace('%','',$rating->RATING);
$numReviews = $rating->REVIEWCOUNT;
}
If I then try to print each element e.g.
echo $part.' '.$rating.' '.$numReviews;
$numReviews is always blank and I have no idea why.
You are replacing the $rating array with a variable, fix it like this:
$part = $rating->VENDORREF;
$rating_string = str_replace('%','',$rating->RATING);
$numReviews = $rating->REVIEWCOUNT;
Check below code. You change the variable names.
$ratings = simplexml_load_file("test.xml");
foreach ($ratings->PRODUCT as $rating){
$part = $rating->VENDORREF;
$ratingVal = str_replace('%','',$rating->RATING);
$numReviews = $rating->REVIEWCOUNT;
}
echo $part.' '.$ratingVal.' '.$numReviews;

Can I use SQL syntax on SimpleXML?

Can I use a WHERE selector (like SQL syntax) on SimpleXML?
Example XML
<?xml version="1.0" encoding="utf-8" ?>
<documentElement>
<row>
<id>1</id>
<name>David</name>
<surname>Johnson</surname>
</row>
<row>
<id>2</id>
<name>Jack</name>
<surname>Nixon</surname>
</row>
</documentElement>
My Example Where Selector
$where = "Jack";
$xml = "example.xml";
$sxml = simplexml_load_string($xml);
foreach ($sxml->row as $data=>$row)
{
if ($where == $data->name) // some code here
else // other some code here
}
Please let me know.
Thank you.
Yes, there is a way: XPath
$where = "Jack";
$xml = "example.xml";
$sxml = simplexml_load_string($xml);
var_dump($sxml->xpath('/documentElement/row/name[.="'.$where.'"]/..'));
No, but you can do this:
$where = "Jack";
$xml = "example.xml";
$sxml = simplexml_load_string($xml);
foreach ($sxml->row as $row)
{
if ($row->name == $where) {
// ...
} else {
// other some code here
}
}

Geting soap xsi:type from server response

I get response from SOAP server which has zero or more transactions of different types in each response.
Each transaction type is extension of base transaction type.
Different transaction types are processed differently.
Is there a way in PHP to get transaction type for each of transactions in response
(other then trying to figure difference in elements within each complex type)?
There is lot of types and lot of elements in each type....
Is there any class which could get this?
Following is just illustration...
<transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type1">
<id>24111</id><something>00000000</something><name>Blah</name>
</transactions>
<transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type8">
<id>24111</id><somethingelse>011</somethingelse>
</transactions>
I 'm not quite sure if this answer fits your question exactly. The following code snippet gets the type attribute value by their given namespaces and not the type of the namespaced value itself.
Done with PHP 's own Document Object Model.
<?php
$str = <<<XML
<content>
<transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type1">
<id>24111</id>
<something>00000000</something>
<name>Blah</name>
</transactions>
<transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type8">
<id>24111</id>
<somethingelse>011</somethingelse>
</transactions>
</content>
XML;
$doc = new DomDocument();
$doc->loadXML($str);
$nodeList = $doc->getElementsByTagName('transactions');
foreach ($nodeList as $element) {
$value = $element->getAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'type');
echo $value . "\n";
}
This will output the two given types "ns2:type1" and "ns2:type8".
I can parse your elements with simple_html_dom.
Here is the link for it.
An example is here :
<?php
include "simple_html_dom.php";
$html_nb = '
<transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type1"><id>24111</id><something>00000000</something><name>Blah</name>
</transactions>
<transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type8"><id>24111</id><somethingelse>011</somethingelse>
</transactions>';
function chtml($str){
if(strpos("<html>", $str) !== false)
return '<html><whole_code>'.$str.'</whole_code></html>';
else
return "<whole_code>".$str."</whole_code>";
}
function find_element_type($str){
if(preg_match_all("/\<(.*?)\>/i", $str, $matches))
return $matches[1][0];
else
return false;
}
function get_xsi_type($str){
if(preg_match_all("/xsi\:type\=\"(.*?)\"/i", $str, $matches))
return $matches[1][0];
else
return false;
}
$html = new simple_html_dom();
$html_2 = new simple_html_dom();
$html->load(chtml($html_nb));
$max_type = 10;
$element = $html->find('whole_code');
$e = $element[0]->innertext;
$html_2->load(chtml($e));
$k = 0;
while($html_2->find("whole_code",false)->children($k) != "")
{
$all = $html_2->find("whole_code",false)->children($k);
echo get_xsi_type($all) . "<br>";
echo find_element_type($all) . " : " .$all."<br>";
$k++;
}
echo "<hr>";
The result :
ns2:type1
transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type1" : 2411100000000Blah
ns2:type8
transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type8" : 24111011

PHP SOAP XML DOM

I have a soap xml that contains a bunch of variables that I need to access. Here is the XML.
`<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<searchPersonsResponse xmlns="">
<searchPersonsReturn>
<attributes>
<attributes>
<name>ercreatedate</name>
<values>
<values>201104070130Z</values>
</values>
</attributes>
<attributes>
<name>status</name>
<values>
<values>Stuff1</values>
<values>Stuff2</values>
<values>Stuff3</values>
<values>Stuff4</values>
<values>Stuff5</values>
<values>Stuff6</values>
<values>Stuff7</values>
</values>
</attributes>
</attributes>
<itimDN>blah</itimDN>
<name>Smith, Bob</name>
<profileName>PER</profileName>
<select>false</select>
</searchPersonsReturn>
</searchPersonsResponse>
</soapenv:Body>
</soapenv:Envelope>
I'm trying to access the inner attribute node and pull out the Name and values into a multidimentional array like this ....
$array["status"][0]="stuff1";
$array["status"][1]="stuff2";
$array["status"][2]="stuff3";
$array["status"][3]="stuff4";
so far I have been able to access the nodes but not really get them the way I want. here is the code I have been playing around with .....
$dom_document = new DOMDocument();
$dom_document->loadXML($thexml);
$tag_els_names = $dom_document->getElementsByTagname('name');
$tag_els_values = $dom_document->getElementsByTagname('values');
$data = array();
$data2 = array();
foreach($tag_els_names as $node){
$data[] = array($node->nodeName => $node->nodeValue);
//grabs all the <name> node values
}
$i=0;$j=0;
foreach($tag_els_values as $node){
$j=0;
foreach($node->childNodes as $child) {
$data2[$i][$j] = $child->nodeValue;
//grabs all the value node values
$j++;
}
$i++;
$j=0;
}
Does anyone know an easy way to do this? I think that I have been looking at this for way to long.
How about something like:
$dom_document = new DOMDocument();
$dom_document->loadXML($thexml);
$xpath = new DOMXpath($dom_document);
$attr = $xpath->evaluate("//attribute/attributes");
$names = array();
$values = array();
$i = 0;
foreach($attr as $attr_node) {
$values[i] = array();
foreach($xpath->evaluate("name", $attr_node) as $name){
$names[] = $name->nodeValue;
}
$foreach($xpath->evaluate("value", $attr_node) as $value){
$values[i][] = $value->nodeValue;
}
i++;
}
This would, however, miss the <name> element that's outside of the <attributes> group. Did you mean to be including that?
I figured this out and thought it could help someone else
$doc = new DOMDocument();
$values=array();
if ($doc->loadXML($temp)) {
$attributes = $doc->getElementsByTagName('attributes');
foreach($attributes as $attribute) {
if($attribute->childNodes->length) {
$previous_nodeValue="";
foreach($attribute->childNodes as $i) {
if($i->nodeValue=="status"){
$previous_nodeValue=$i->nodeValue;
}
if($i->nodeName=="values" && $previous_nodeValue== "status"){
foreach($i->childNodes as $j){
$values[]=$j->nodeValue;
}
}
}
$previous_nodeValue="";
}
}
}

Categories