i want to convert to csv from xml file only the specified values...
XML File:
<?xml version="1.0" encoding="UTF-8"?>
<file>
<PRODUCT sku="12345" price="129"/>
<PRODUCT sku="12356" price="150"/>
<PRODUCT sku="12367" price="160"/>
<PRODUCT sku="12389" price="190"/>
</file>
CSV File.
SKU,PRICE
12345,129
12356,150
12367,160
12389,190
but i want to get the price only for 12345, 12367 and 12389
This is my start file:
<?php
$filexml = 'file.xml';
if (file_exists($filexml)){
$xml = simplexml_load_file($filexml);
$file = fopen('file.csv', 'w');
$header = array('sku', 'price');
fputcsv($file, $header, ',', '"');
foreach ($xml->PRODUCT as $product){
$item = array();
$value1 = $product->attributes()->sku;
$value2 = $product->attributes()->price;
$item[] = $value1;
$item[] = $value2;
fputcsv($file, $item, ',', '"');
}
fclose($file);
}
?>
an option can be this, but is returning me Array, maybe is wrong something there.
<?php
$filexml = 'file.xml';
if (file_exists($filexml)){
$xml = simplexml_load_file($filexml);
$file = fopen('file.csv', 'w');
$header = array('sku', 'price');
$customvalue = array('12345', '12367', '12389');
fputcsv($file, $header, ',', '"');
foreach ($xml->PRODUCT as $product){
$item = array();
$value1 = $product->attributes()->sku;
$value2 = $product->attributes()->price;
$item[] = $customvalue;
$item[] = $value2;
fputcsv($file, $item, ',', '"');
}
fclose($file);
}
?>
Thanks
Ryan Solution:
<?php
$filexml = 'file.xml';
if (file_exists($filexml)){
$xml = simplexml_load_file($filexml);
$file = fopen('file.csv', 'w');
$header = array('sku', 'price');
$customvalue = array('12345', '12367', '12389');
fputcsv($file, $header, ',', '"');
foreach ($xml->PRODUCT as $product){
if ( in_array($product->attributes()->sku, $customvalue ) ) {
$item = array ();
$item[] = $product->attributes()->sku;
$item[] = $product->attributes()->price;
fputcsv($file, $item, ',', '"');
}
fclose($file);
}
?>
but the output is true and good, but i need to remove the unnecessary codes because in large file with about 7000 codes this get a 300mb csv file.
This is the output.
12345,129
12345,129,12356,150
12367,160
12389,190
in large files im getting this:
12345,129
12345,129,123456,150,12367,160
12389,190,123456,150,12367,160,12345,129
12399,200
12399,200,12345,129,12389,160,123456,150
12399,200,12345,129,12389,160,123456,150,12399,200,12345,129,12389,160,123456,150
the specified codes in array are first in the right column, but at the end this is creating a big csv file. and result timeout or memory out.
Thanks
You are on the right track. Add a check to ensure that you read only the specified rows, and simplify the pulling out of the fields you want, something like this (just the foreach loop, the rest while stay the same:
foreach ($xml->PRODUCT as $product){
if ( in_array($product->attributes()->sku, $customvalue ) ) {
$item = array ();
$item[] = $product->attributes()->sku;
$item[] = $product->attributes()->price;
fputcsv($file, $item, ',', '"');
}
Related
i want to read test.txt file line by line that i converted it to object but my problem is it just read line 1 and something is wrong because loading is little long
$file = fopen(__DIR__.'/test.txt','r');
while (!feof($file)){
$file = fgets($file);
$obj = json_decode($file);
echo $obj->sid;
echo "<hr>";
}
this my test.txt:
{"sid":5555,"trans-id":"PROV_149663920543900000801","status":"0","base-price-point":"0","msisdn":"989905978846","keyword":"sub1","validity":1}
{"sid":2244,"trans-id":"PROV_149663920543900000801","status":"0","base-price-point":"0","msisdn":"989905978846","keyword":"sub1","validity":1}
You are overwriting $file on line 3 of your code. Change it to $line and you are good to go.
$file = fopen(__DIR__.'/test.txt','r');
while (!feof($file)){
$line = fgets($file);
$obj = json_decode($line);
echo $obj->sid;
echo "<hr>";
}
Try this:
<?php
$filename= __DIR__.'/test.txt';
$array = explode("\n", file_get_contents($filename));
foreach ( $array as $line)
{
$obj = json_decode($line);
echo $obj->sid;
echo "<hr>";
}
?>
Use the file() function:
$contents = file(__DIR__.'/test.txt');
foreach ($contents as $line)
{
$obj = json_decode($line);
echo $obj->sid;
echo "<hr>";
}
The file() function read a file and create an array with each line of the file's contents.
I'd suggest using file to read the file as this generates the individual lines as array entries so you can iterate though each line using a foreach
$file=__DIR__ . '/json_src.txt';
$lines=file($file);
foreach( $lines as $line ){
$json=json_decode( $line );
printf('%s<hr />', $json->sid );
}
I have a CSV file and I want to check if the row contains a special title. Only if my row contains a special title it should be converted to XML, other stuff added and so on.
My question now is, how can I iterate through the whole CSV file and get for every title the value in this field?
Because if it matches my special title I just want to convert the specified row where the title is matching my title. Maybe also an idea how I can do that?
Sample: CSV File
I must add that feature to my actual function. Because my actual function is just is converting the whole CSV to XML. But I just want to convert the specified rows.
My actual function:
function csvToXML($inputFilename, $outputFilename, $delimiter = ',')
{
// Open csv to read
$inputFile = fopen($inputFilename, 'rt');
// Get the headers of the file
$headers = fgetcsv($inputFile, 0, $delimiter);
// Create a new dom document with pretty formatting
$doc = new DOMDocument('1.0', 'utf-8');
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
// Add a root node to the document
$root = $doc->createElement('products');
$root = $doc->appendChild($root);
// Loop through each row creating a <row> node with the correct data
while (($row = fgetcsv($inputFile, 0, $delimiter)) !== false) {
$container = $doc->createElement('product');
foreach ($headers as $i => $header) {
$child = $doc->createElement($header);
$child = $container->appendChild($child);
$value = $doc->createTextNode($row[$i]);
$value = $child->appendChild($value);
}
$root->appendChild($container);
}
$strxml = $doc->saveXML();
$handle = fopen($outputFilename, 'w');
fwrite($handle, $strxml);
fclose($handle);
}
Just check the title before adding the rows to XML. You could do it by adding the following lines:
while (($row = fgetcsv($inputFile, 0, $delimiter)) !== false) {
$specialTitles = Array('Title 1', 'Title 2', 'Title 3'); // titles you want to keep
if(in_array($row[1], $specialTitles)){
$container = $doc->createElement('product');
foreach ($headers as $i => $header) {
$child = $doc->createElement($header);
$child = $container->appendChild($child);
$value = $doc->createTextNode($row[$i]);
$value = $child->appendChild($value);
}
$root->appendChild($container);
}
}
I need to convert an XML file to CSV.
I have a script but I am unsure of how to use it to my needs.
Here is the script
$filexml='141.xml';
if (file_exists($filexml)) {
$xml = simplexml_load_file($filexml);
$f = fopen('141.csv', 'w');
foreach ($xml->item as $item) {
fputcsv($f, get_object_vars($item),',','"');
}
fclose($f);
}
The file is called 141.xml and here is some of the code in the XML which I need to convert.
<?xml version="1.0" encoding="UTF-8" ?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<item>
<title><![CDATA[//title name]]></title>
<link><![CDATA[https://www.someurl.co.uk]]></link>
<description><![CDATA[<p><span>Demo Description</span></p>]]></description>
<g:id><![CDATA[4796]]></g:id>
<g:condition><![CDATA[new]]></g:condition>
<g:price><![CDATA[0.89 GBP]]></g:price>
<g:availability><![CDATA[in stock]]></g:availability>
<g:image_link><![CDATA[https://image-location.png]]></g:image_link>
<g:service><![CDATA[Free Shipping]]></g:service>
<g:price><![CDATA[0 GBP]]></g:price>
</item>
I am running the script from SSH using:
php /var/www/vhosts/mywebsite.co.uk/httpdocs/xml/convert.php
If you can help me, it would be really appreciated :)
Thanks
Consider passing XML data into an array $values and exporting array by row to csv.
Specifically, using the xpath() function for the XML extraction, iterate through each <item> and extract all its children's values (/*). By the way, I add headers in the CSV file.
$filexml='141.xml';
if (file_exists($filexml)) {
$xml = simplexml_load_file($filexml);
$i = 1; // Position counter
$values = []; // PHP array
// Writing column headers
$columns = array('title', 'link', 'description', 'id', 'condition',
'price', 'availability', 'image_link', 'service', 'price');
$fs = fopen('141.csv', 'w');
fputcsv($fs, $columns);
fclose($fs);
// Iterate through each <item> node
$node = $xml->xpath('//item');
foreach ($node as $n) {
// Iterate through each child of <item> node
$child = $xml->xpath('//item['.$i.']/*');
foreach ($child as $value) {
$values[] = $value;
}
// Write to CSV files (appending to column headers)
$fs = fopen('141.csv', 'a');
fputcsv($fs, $values);
fclose($fs);
$values = []; // Clean out array for next <item> (i.e., row)
$i++; // Move to next <item> (i.e., node position)
}
}
Try out below code. And the XML file is having syntax error, the closing tag for rss and channel is missing.
$filexml='141.xml';
if (file_exists($filexml))
{
$xml = simplexml_load_file($filexml);
$f = fopen('141.csv', 'w');
createCsv($xml, $f);
fclose($f);
}
function createCsv($xml,$f)
{
foreach ($xml->children() as $item)
{
$hasChild = (count($item->children()) > 0)?true:false;
if( ! $hasChild)
{
$put_arr = array($item->getName(),$item);
fputcsv($f, $put_arr ,',','"');
}
else
{
createCsv($item, $f);
}
}
}
I am trying to make some dynamically made INI files for some GPRS printers. I have the original INI file here and wish to use PHP to make bulk copies of the file with certain changes per printer. I can push the updated INI file to them direct but I am having issues getting the formatting of the INI file right. I have a text file just now with all the settings. I am using this code as a proof of concept but what happens is that it removed all spaces and all line brakes causing it not to work! Is there anyway of getting this to work? Creating an array for all the data (We are talking 75 sections of data. Not all will change per printer mind.)
This is my code:
$replace = array("ID"=>"AC001");
$inifile = 'ini.txt';
$fh = fopen($inifile, 'r');
$inifile = fread($fh, filesize($inifile));
fclose($fh);
foreach($replace as $key => $value)
{
$template = str_replace('{$'.$key.'}', $value, $inifile);
}
echo $template;
$filename = $replace["ID"].".ini";
$handle = fopen($filename, 'x+');
fwrite($handle, $template);
fclose($handle);
Data format:
[section number (1-75)]
Name=Parm name
NameEn=Parm name
Command= Parm (demo case: {$id})
IsValid=1
DataMode=1
IsHide=1
[section number (1-75)]
Name=Parm name
NameEn=Parm name
Command= Parm
IsValid=1
DataMode=1
IsHide=1
What comes out the other side is just one big long line of text.
OK came up with a better option that works! Just now that its broken the string replace function!
function arr2ini(array $a, array $parent = array())
{
$out = '';
foreach ($a as $k => $v)
{
if (is_array($v))
{
//subsection case
//merge all the sections into one array...
$sec = array_merge((array) $parent, (array) $k);
//add section information to the output
$out .= '[' . join('.', $sec) . ']' . PHP_EOL;
//recursively traverse deeper
$out .= arr2ini($v, $sec);
}
else
{
//plain key->value case
$out .= "$k=$v" . PHP_EOL;
}
}
return $out;
}
$replace = array("ID"=>"AC001");
$inifile = 'ini.ini';
$files = parse_ini_file("$inifile",true);
foreach($replace as $key => $value)
{
echo $template = str_replace('{$'.$key.'}', $value, $files);
}
var_dump($template);
$filename = $replace["ID"].".ini";
$ini = arr ; 2ini($template);
echo $ini;
$handle = fopen($filename, 'x+');
fwrite($handle, $ini);
fclose($handle);
so i have the following code:
myarray[1] = item1, element1, element2
myarray[2] = item2, element1, element2
$outfile = "csv.txt";
$filewriter = fopen($outfile, "w"); // open for write
foreach($myarray as $item) {
fwrite($filewriter, $item);
}
which produces the following in the txt file:
item1,element1,element2item2,element1,element2
if i try to use "\n" it produces this output:
item1,element1,element2
(blank line)
item2,element1,element2
how do i get it too:
item1,element1,element2
item2,element1,element2
This is the \n
function writetofile($myarray){
$outfile = "csv.txt";
$filewriter = fopen($outfile,"w"); // open for write
$item=$myarray[0]."\n".$myarray[1];
fwrite($filewriter, $item);
Thanks
Try with the code below
<?php
$myarray[1] = 'item1, element1, element2';
$myarray[2] = 'item2, element1, element2';
$outfile = "csv.txt";
$filewriter = fopen($outfile, "w"); // open for write
foreach($myarray as $item) {
fwrite($filewriter, $item.'
');
}
Why not like this?
<?php
$myarray = array("item1 ,", "element1 ,", "element2 \r\n","item2 ,","element1 ,","element2");
$array_length = count($myarray); // Array length
$outfile = "csv.txt";
$filewriter = fopen($outfile, "w");
for($x=0;$x<$array_length;$x++)
{
echo $myarray[$x];
fwrite($filewriter, $myarray[$x]);
}
?>
The following code gives you (csv.txt) :
item1 ,element1 ,element2
item2 ,element1 ,element2