loop in simplexml load file - php

I am using the following code to parse the XML data to MySQL table and it is working as expected.
<?php
$sxe = simplexml_load_file("$myfile");
foreach($sxe->AUTHAD as $sales) {
$authad="insert into test.authad values ('".mysql_real_escape_string($sales->LOCALDATE)."','".mysql_real_escape_string($sales->LOCALTIME)."','".mysql_real_escape_string($sales->TLOGID)."','" ...
?>
The problem is that when I get a new xml file with different format, I can not use the above insert into statement and have to change the parameters manually. For e.g.
$authadv_new="insert into test.authad values ('".mysql_real_escape_string($sales->NEW1)."','".mysql_real_escape_string($sales->NEW2)."','".mysql_real_escape_string($sales->NEW3)."','" ...
Is there any way to automate this? I mean the PHP code should be able to anticipate the parameters and generate the mysql_real_escape_string($sales->NEW1) to NEW10 values using a loop.

While satrun77's example works fine, you can use slightly less code and stick to the advantages of the simplexml object by using its "children()" method:
$sxe = simplexml_load_string($xml);
foreach($sxe->AUTHAD as $sales) {
foreach ($sales->children() as $child) {
$children[]="'".mysql_real_escape_string($child)."'";
}
$authad="insert into test.authad values (".implode($children,",").");";
}

Maybe something like this using a dynamic variable $var?
<?php
$values = array();
for($i = 1; $i < 11; $i++) {
$var = "NEW".$i;
$values[] = "'".mysql_real_escape_string($sales->$var)."'";
}
$string = join(",", $values);

I hope this is what you are looking for?
$string = '<?xml version="1.0" encoding="UTF-8" ?>
<root>
<AUTHAD>
<NEW1>New 1</NEW1>
<NEW2>New 2</NEW2>
<NEW3>New 3</NEW3>
<NEW4>New 4</NEW4>
<NEW5>New 5</NEW5>
<NEW6>New 6</NEW6>
</AUTHAD>
<AUTHAD>
<NEW1>New 11</NEW1>
<NEW2>New 22</NEW2>
<NEW3>New 33</NEW3>
</AUTHAD>
</root>
';
$sxe = simplexml_load_string($string);
foreach($sxe->AUTHAD as $sales) {
if (count($sales) > 0) {
$values = array();
foreach($sales as $key => $sale) {
$values[] = "'" . mysql_real_escape_string($sale) . "'";
}
$authadv_new="insert into test.authad values (" . join(', ', $values) . ")";
echo $authadv_new.'<br >';
}
}

You're looking for get_object_vars() to iterate over the object members:
<?php
mysql_connect( 'localhost', 'root', 'moin' );
$sxe = simplexml_load_file( $argv[1] );
var_dump( $sxe );
$sql = "insert into test.authad values (";
foreach($sxe->AUTHAD as $sales) {
$members = get_object_vars( $sales );
$values = array();
foreach ( $members as $name => $value ) {
echo "$name : $value\n";
$values[] = "'" . mysql_real_escape_string( $value ) . "'";
}
$sql .= join( $values, ', ' );
}
$sql .= ")\n";
echo $sql;
The input is this file:
<sxe>
<AUTHAD>
<eins>one</eins>
<zwei>two':-)</zwei>
<drei>three;"'</drei>
</AUTHAD>
</sxe>
I'm getting the following result here:
insert into test.authad values ('one', 'two\':-)', 'three;\"\'')

If you're not concerned about the order of data between each XML you can just implode the object rather than pick out the specific values each time. Doing an implode also allows you to avoid the loop.
INSERT INTO test.authad VALUES('".implode("','", mysql_real_escape_string($sxe->AUTHAD))."')

Related

Extracting a specific part of a string

I have this string:
[25-03-15, 1236], [26-03-15, 3000], [27-03-15, 3054], [30-03-15, 4000]
I want to get two parts from it as below:
['25-03-15','26-03-15','27-03-15','30-03-2015']
and
[1236,3000,3054,4000]
Please guide me how I can perform this task.
PS: I am working of view page of codeigniter.
I'm getting the first thing as:
<?php
$usd=$this->db->query('select transaction_date, SUM(amount) as total
from transactions GROUP BY transaction_date')->result_array();
$str = '';
for($i=0; $i<count($usd); $i++){
if($i!=0){
$str = $str.', ['.date('d-m-y', strtotime($usd[$i]["transaction_date"])).', '.$usd[$i]["total"].']';
}else{
$str = $str.'['.date('d-m-y', strtotime($usd[$i]["transaction_date"])).', '.$usd[$i]["total"].']';
}
}
echo $str;
?>
Try this..
$date = '';
$total = '';
for($i=0; $i<count($usd); $i++){
if($i!=0){
$date .= date('d-m-y', strtotime($usd[$i]["transaction_date"])).', ';
$total .= $usd[$i]["total"].', ';
}else{
$date .= date('d-m-y', strtotime($usd[$i]["transaction_date"])).', ';
$total .= $usd[$i]["total"].', ';
}
}
echo $finaldate='['. $date.']';
echo $finaltotal='['. $total.']';
I don't see any reason why you need to save this data from your db in a string. Just save it in an array and it is that easy:
So here I save your data in an array, so that you get this structure:
array(
array(25-03-15, 1236),
array(26-03-15, 3000),
array(27-03-15, 3054),
array(30-03-15, 4000)
)
The you can simply use array_column() to extract the single columns, like this:
<?php
$usd = $this->db->query('select transaction_date, SUM(amount) as total
from transactions GROUP BY transaction_date')->result_array();
foreach($usd as $k => $v)
$result[] = [date('d-m-y', strtotime($usd[$k]["transaction_date"])), $usd[$k]["total"]];
$partOne = array_column($result, 0);
$partTwo = array_column($result, 1);
?>
Also if you then need this data in a string as you said in the comments you can simply transform it:
I will pass this extracted data to a graph that accepts this kind of data – Shahid Rafiq 6 mins ago
Just use this:
echo $str = "[" . implode("],[", array_map(function($v){
return implode(",", $v);
}, $usd)) . "]";
output:
[25-03-15, 1236], [26-03-15, 3000], [27-03-15, 3054], [30-03-15, 4000]
EDIT:
If you also want the parts as string just simply do this:
$partOne = "[" . implode("],[", array_column($arr, 0)) . "]";
$partTwo = "[" . implode("],[", array_column($arr, 1)) . "]";
output:
[25-03-15],[26-03-15],[27-03-15],[30-03-15]
[1236],[3000],[3054],[4000]

DOMdocument search for tag

i am trying to do this:
i have several thousand xml files, i am reading them, and i am looking for special text inside an xml with specific tag, but those tags which are having the text i need, are different. what i did till now is this:
$xml_filename = "xml/".$anzeigen_id.".xml";
$dom = new DOMDocument();
$dom->load($xml_filename);
$value = $dom->getElementsByTagName('FormattedPositionDescription');
foreach($value as $v){
$text = $v->getElementsByTagName('Value');
foreach($text as $t){
$anzeige_txt = $t->nodeValue;
$anzeige_txt = utf8_decode($anzeige_txt);
$anzeige_txt = mysql_real_escape_string($anzeige_txt);
echo $anzeige_txt;
$sql = "INSERT INTO joinvision_anzeige(`firmen_id`,`anzeige_id`,`anzeige_txt`) VALUES ('$firma_id','$anzeigen_id','$anzeige_txt')";
$sql_inserted = mysql_query($sql);
if($sql_inserted){
echo "'$anzeigen_id' from $xml_filename inserted<br />";
}else{
echo mysql_errno() . ": " . mysql_error() . "\n";
}
}
}
now what i need to do is this:
look for FormattedPositionDescription in xml and if there is not this tag there, then look for anothertag in that same xml file..
how can i do this, thanks for help in advance
Just check the length property of the DOMNodeList:
$value = $dom->getElementsByTagName('FormattedPositionDescription');
if($value->length > 0)
{
// found some FormattedPositionDescription
}
else
{
// didn't find any FormattedPositionDescription, so look for anothertag
$list = $dom->getElementsByTagName('anothertag');
}

Prepend character to array of items in PHP

I am trying to take a string like...
php,mysql,css
and turn it into .. #php #mysql #css
What I have so far...
$hashTagStr = "php,mysql,css";
$hashTags = explode(",", $hashTagStr);
foreach($hashTags as $k => $v){
$hashTagsStr = '';
$hashTagsStr .= '#'.$v.' ';
}
echo $hashTagsStr;
?>
Problem is it only prints #css
How about this:
$hashTagStr = "php,mysql,css";
$hashTags = explode(",", $hashTagStr);
$hashTagStr = '#' . implode( ' #', $hashTags );
...or:
$hashTagStr = "php,mysql,css";
$hashTagStr = '#' . str_replace( ',', ' #', $hashTagStr );
That's because every time the loop runs you're clearing out $hashTagsStr by doing:
$hashTagsStr = '';
Change it to:
$hashTagStr = "php,mysql,css";
$hashTags = explode(",", $hashTagStr);
$hashTagsStr = '';
foreach($hashTags as $k => $v){
$hashTagsStr .= '#'.$v.' ';
}
echo $hashTagsStr;
Pass your values by reference:
$hashTags = array("php","mysql","css");
foreach ( $hashTags as &$v ) $v = "#" . $v;
Then hammer out the results:
// #php #mysql #css
echo implode( " ", $hashTags );
Demo: http://codepad.org/zbtLF5Pk
Let's examine what you're doing:
// You start with a string, all good.
$hashTagStr = "php,mysql,css";
// Blow it apart into an array - awesome!
$hashTags = explode( "," , $hashTagStr );
// Yeah, let's cycle this badboy!
foreach($hashTags as $k => $v) {
// Iteration 1: Yeah, empty strings!
// Iteration 2: Yeah, empty...wait, OMG!
$hashTagsStr = '';
// Concat onto an empty var
$hashTagsStr .= '#'.$v.' ';
}
// Show our final output
echo $hashTagsStr;
looks like a Job for array_walk
$hashTagStr = "php,mysql,css";
$hashTags = explode(",", $hashTagStr);
array_walk($hashTags, function(&$value){ $value = "#" . $value ;} );
var_dump(implode(" ", $hashTags));
Output
string '#php #mysql #css' (length=16)
You should move the $hashTagsStr = '' line outsite the foreach loop, otherwise you reset it each time
You are defining the variable $hashTagsStrinside the loop.
<?php
$hashTagStr = "php,mysql,css";
$hashTags = explode(",", $hashTagStr);
$hashTagsStr = '';
foreach($hashTags as $k => $v){
$hashTagsStr .= '#'.$v.' ';
}
echo $hashTagsStr;
Anyway, I think this would be simpler:
<?php
$hashTagStr = "php,mysql,css";
$hashTagStr = '#' . str_replace(',', ' #', $hashTagStr);
echo $hashTagStr;
During each iteration of the loop, you are doing $hashTagsStr = '';. This is setting the variable to '', and then appending the current tag. So, when it's done, $hashTagsStr will only contain the last tag.
Also, a loop seems like too much work here, you can much easier just replace the , with #. No need to break it into an aray, no need to loop. Try this:
$hashTagStr = "php,mysql,css";
$hashTagStr = '#'.str_replace(',', ' #', $hashTagStr);
function prepend( $pre, $array )
{
return array_map(
function($t) use ($pre) { return $pre.$t; }, $array
);
}
What you semantically have in your string is an array. ➪ So better explode as soon as possible, and keep working with your array, as long as possible.
Closures & anonymous functions as shown work in PHP 5.4+.

How to read json properties using PHP

How to get all pid and styles attribute from following json data with minimum loop in php
{"general":{"note":{"display":false}},"elements":{"the-1":{"index":1,"src":"shirt1.png","pid":"pid-3563130","angle":0,"styles":"background:transparent;top:51.80000305175781px;left:122px;width:80px;height:80px;","background":"transparent","pos":{"top":51.80000305175781,"left":122},"size":{"width":80,"height":80},"details":{"other":""}},"the-2":{"index":2,"src":"shirt2.png","pid":"pid-132002","angle":0,"styles":"background:transparent;top:44.80000305175781px;left:155px;width:80px;height:80px;","background":"transparent","pos":{"top":44.80000305175781,"left":155},"size":{"width":80,"height":80},"details":{"other":""}}}}
Thanks
$str = '{"general":{"note":{"display":false}},"elements":{"the-1":{"index":1,"src":"shirt1.png","pid":"pid-3563130","angle":0,"styles":"background:transparent;top:51.80000305175781px;left:122px;width:80px;height:80px;","background":"transparent","pos":{"top":51.80000305175781,"left":122},"size":{"width":80,"height":80},"details":{"other":""}},"the-2":{"index":2,"src":"shirt2.png","pid":"pid-132002","angle":0,"styles":"background:transparent;top:44.80000305175781px;left:155px;width:80px;height:80px;","background":"transparent","pos":{"top":44.80000305175781,"left":155},"size":{"width":80,"height":80},"details":{"other":""}}}}';
$arr = json_decode($str, true);
foreach ($arr['elements'] as $element) {
echo 'pid: ' . $element['pid'] . '<br />';
echo 'styles: ' . $element['styles'] . '<br />';
}
use json_decode function in PHP to get assosiative array.
<?php
$myJson = '{"general":{"note":{"display":false}},"elements":{"the-1":{"index":1,"src":"shirt1.png","pid":"pid-3563130","angle":0,"styles":"background:transparent;top:51.80000305175781px;left:122px;width:80px;height:80px;","background":"transparent","pos":{"top":51.80000305175781,"left":122},"size":{"width":80,"height":80},"details":{"other":""}},"the-2":{"index":2,"src":"shirt2.png","pid":"pid-132002","angle":0,"styles":"background:transparent;top:44.80000305175781px;left:155px;width:80px;height:80px;","background":"transparent","pos":{"top":44.80000305175781,"left":155},"size":{"width":80,"height":80},"details":{"other":""}}}}';
$myArray = json_decode($myJson,true);
$myInnerArray = $myArray['elements'];
$styles = array();
foreach($myInnerArray as $element)
$styles[] = $element['styles'];
print_r($styles);
?>
PHP has great abilities to handle json.
Let's assume the JSON string you've posted above is stored in a PHP variable $myJSON.
So we can easily store an associative array of these values into $myJSONArray like so:
$myJSONArray = json_decode( $myJSON, true );
So, now we just loop through:
foreach( $myJSONArray['elements'] as $arr => $key )
echo( "A PID: " . $key['pid'] . "\n" );
See it in action on Codepad.
$json = json_decode('{"general":{"note":{"display":false}},"elements":{"the-1":{"index":1,"src":"shirt1.png","pid":"pid-3563130","angle":0,"styles":"background:transparent;top:51.80000305175781px;left:122px;width:80px;height:80px;","background":"transparent","pos":{"top":51.80000305175781,"left":122},"size":{"width":80,"height":80},"details":{"other":""}},"the-2":{"index":2,"src":"shirt2.png","pid":"pid-132002","angle":0,"styles":"background:transparent;top:44.80000305175781px;left:155px;width:80px;height:80px;","background":"transparent","pos":{"top":44.80000305175781,"left":155},"size":{"width":80,"height":80},"details":{"other":""}}}}', true);
$elements = $json['elements'];
foreach($elements as $element){
$pid = $element['pid'];
$styles = $element['styles'];
echo $pid.': '.$styles.'<br />';
}
Example here

Need some help with XML parsing

The XML feed is located at: http://xml.betclick.com/odds_fr.xml
I need a php loop to echo the name of the match, the hour, and the bets options and the odds links.
The function will select and display ONLY the matchs of the day with streaming="1" and the bets type "Ftb_Mr3".
I'm new to xpath and simplexml.
Thanks in advance.
So far I have:
<?php
$xml_str = file_get_contents("http://xml.betclick.com/odds_fr.xml");
$xml = simplexml_load_string($xml_str);
// need xpath magic
$xml->xpath();
// display
?>
Xpath is pretty simple once you get the hang of it
you basically want to get every match tag with a certain attribute
//match[#streaming=1]
will work pefectly, it gets every match tag from underneath the parent tag with the attribute streaming equal to 1
And i just realised you also want matches with a bets type of "Ftb_Mr3"
//match[#streaming=1]/bets/bet[#code="Ftb_Mr3"]
This will return the bet node though, we want the match, which we know is the grandparent
//match[#streaming=1]/bets/bet[#code="Ftb_Mr3"]/../..
the two dots work like they do in file paths, and gets the match.
now to work this into your sample just change the final bit to
// need xpath magic
$nodes = $xml->xpath('//match[#streaming=1]/bets/bet[#code="Ftb_Mr3"]/../..');
foreach($nodes as $node) {
echo $node['name'].'<br/>';
}
to print all the match names.
I don't know how to work xpath really, but if you want to 'loop it', this should get you started:
<?php
$xml = simplexml_load_file("odds_fr.xml");
foreach ($xml->children() as $child)
{
foreach ($child->children() as $child2)
{
foreach ($child2->children() as $child3)
{
foreach($child3->attributes() as $a => $b)
{
echo $a,'="',$b,"\"</br>";
}
}
}
}
?>
That gets you to the 'match' tag which has the 'streaming' attribute. I don't really know what 'matches of the day' are, either, but...
It's basically right out of the w3c reference:
http://www.w3schools.com/PHP/php_ref_simplexml.asp
I am using this on a project. Scraping Beclic odds with:
<?php
$match_csv = fopen('matches.csv', 'w');
$bet_csv = fopen('bets.csv', 'w');
$xml = simplexml_load_file('http://xml.cdn.betclic.com/odds_en.xml');
$bookmaker = 'Betclick';
foreach ($xml as $sport) {
$sport_name = $sport->attributes()->name;
foreach ($sport as $event) {
$event_name = $event->attributes()->name;
foreach ($event as $match) {
$match_name = $match->attributes()->name;
$match_id = $match->attributes()->id;
$match_start_date_str = str_replace('T', ' ', $match->attributes()->start_date);
$match_start_date = strtotime($match_start_date_str);
if (!empty($match->attributes()->live_id)) {
$match_is_live = 1;
} else {
$match_is_live = 0;
}
if ($match->attributes()->streaming == 1) {
$match_is_running = 1;
} else {
$match_is_running = 0;
}
$match_row = $match_id . ',' . $bookmaker . ',' . $sport_name . ',' . $event_name . ',' . $match_name . ',' . $match_start_date . ',' . $match_is_live . ',' . $match_is_running;
fputcsv($match_csv, explode(',', $match_row));
foreach ($match as $bets) {
foreach ($bets as $bet) {
$bet_name = $bet->attributes()->name;
foreach ($bet as $choice) {
// team numbers are surrounded by %, we strip them
$choice_name = str_replace('%', '', $choice->attributes()->name);
// get the float value of odss
$odd = (float)$choice->attributes()->odd;
// concat the row to be put to csv file
$bet_row = $match_id . ',' . $bet_name . ',' . $choice_name . ',' . $odd;
fputcsv($bet_csv, explode(',', $bet_row));
}
}
}
}
}
}
fclose($match_csv);
fclose($bet_csv);
?>
Then loading the csv files into mysql. Running it once a minute, works great so far.

Categories