【发布时间】:2017-10-16 18:24:06
【问题描述】:
我正在尝试将我的 Yahoo Store 目录导入 Google 购物。 Yahoo 目录导出为 CSV,但它必须是 XML。我正在创建一个 PHP 脚本来进行转换。到目前为止,我已经创建了所有适当的元素,并根据需要转换了名称和值,但在运输价格元素方面遇到了问题。它在值之前自动关闭,即:
<g:price/>PRICE
而不是
<g:price>PRICE</g:price>
我相当肯定它与 appendChild 或嵌套有关,但我仍在学习,这是我第一次在 PHP 中使用 CSV 或 XML。对于解决此问题和清理我凌乱的代码的任何建议或想法,我将不胜感激。
CSV 示例(input.csv),只有一个产品:
id,name,caption,product-url,c4-tab4-local,c4-tab5-local,condition,orderable,price,sale-price,code,label,ship-weight
"10auodgrwibl","5 PACK Magnet for Military Style Steal Ammo Can","Our Military Ammo Can Magnets will stick to any side of a standard issue military ammo can like the one pictured. Use these to mark your can(s) so you don't have to open them up to see whats inside. Great for preppers! Each magnet measures approx. 3.54"" x 2.05"" or 90 x 52 mm
Wholesale/Dealer Inquires welcome.","http://www.example.com.com/10auodgrwibl.html","https://sep.yimg.com/ca/I/yhst-057809732878263172244949_2487_75897626","Ammo Can Magnets","New","Yes","12.98","4.99","PI-ACM10MMOD","Example Manufacturer","0.07"
PHP:
<?php
// Set Store Info here
$storetitle = "Example Store"; // Store/business name
$url = "http://www.example.com"; // store URL
$tagline = "Online Store"; // store tagline/catch phrase
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', true);
ini_set('auto_detect_line_endings', true);
$inputFilename = 'input.csv';
$outputFilename = 'output.xml';
// Open csv to read
$inputFile = fopen($inputFilename, 'rt');
// Get the headers of the file
$headers = fgetcsv($inputFile);
// Create a new dom document with pretty formatting
$doc = new DomDocument('1.0', 'utf-8');
$doc->formatOutput = true;
// Add a root node to the document
$root = $doc->createElement('rss');
$root = $doc->appendChild($root);
$root->setAttribute("version", "2.0");
$root->setAttributeNS('http://www.w3.org/2000/xmlns/' ,'xmlns:g', 'http://base.google.com/ns/1.0');
$root->setAttributeNS('http://www.w3.org/2000/xmlns/' ,'xmlns:c', 'http://base.google.com/cns/1.0');
// Add channel node to the document
$channel = $doc->createElement('channel');
$root->appendChild($channel);
// Add title
$title = $doc->createElement('title');
$value = $doc->createCDATASection($storetitle);
$value = $title->appendChild($value);
$channel->appendChild($title);
// Add URL
$link = $doc->createElement('link');
$value = $doc->createCDATASection($url);
$value = $link->appendChild($value);
$channel->appendChild($link);
// Add description
$desc = $doc->createElement('description');
$value = $doc->createCDATASection($tagline);
$value = $desc->appendChild($value);
$channel->appendChild($desc);
// Loop through each row creating a <row> node with the correct data
while (($row = fgetcsv($inputFile)) !== FALSE)
{
$container = $doc->createElement('item');
foreach($headers as $i => $header)
{
if($row[4] == NULL){}
else {
if($header == "id"){$child = $doc->createElement('g:id');}
elseif($header == "name"){$child = $doc->createElement('title');}
elseif($header == "caption"){$child = $doc->createElement('description');}
elseif($header == "product-url"){$child = $doc->createElement('link');}
elseif($header == "c4-tab5-local"){$child = $doc->createElement('g:product_type');}
elseif($header == "c4-tab4-local"){$child = $doc->createElement('g:image_link');}
elseif($header == "condition"){$child = $doc->createElement('g:condition');}
elseif($header == "orderable"){$child = $doc->createElement('g:availability');}
elseif($header == "price"){$child = $doc->createElement('g:price');}
elseif($header == "sale-price"){$child = $doc->createElement('g:sale_price');}
elseif($header == "code"){$child = $doc->createElement('g:mpn');}
elseif($header == "label"){$child = $doc->createElement('g:brand');}
elseif($header == "ship-weight"){$child = $doc->createElement('g:shipping');}
else{$child = $doc->createElement($header);}
$child = $container->appendChild($child);
if ($header == "price" || $header == "sale-price"){$value = $doc->createCDATASection($row[$i] . " USD");}
elseif ($header == "orderable"){
if ($row[$i] == "Yes"){$value = $doc->createCDATASection('in stock');}
else{$value = $doc->createCDATASection('out of stock');}
}
elseif ($header == "ship-weight"){
$weight = $row[$i];
$country = $doc->createElement('g:country');
$value = $doc->createTextNode('US');
$value = $country->appendChild($value);
$child->appendChild($country);
$method = $doc->createElement('g:service');
$value = $doc->createTextNode('Ground');
$value = $method->appendChild($value);
$child->appendChild($method);
$shipcost = $doc->createElement('g:price');
if($weight <= "1"){$value = $doc->createTextNode('6.95 USD');}
else{
$math = ceil($weight) *2 + 6.95;
$value = $doc->createTextNode($math . ' USD');
}
$value = $shipcost->appendChild($value);
$child->appendChild($shipcost);
}
else{$value = $doc->createCDATASection($row[$i]);}
$value = $child->appendChild($value);
}
}
$channel->appendChild($container);
}
$strxml = $doc->saveXML();
$handle = fopen($outputFilename, "w");
fwrite($handle, $strxml);
fclose($handle);
?>
【问题讨论】:
-
原来为每个 createElement() 分配 $child 的 foreach 循环是问题所在。我将其更改为对需要定位的元素使用唯一变量,现在一切正常。有人可以将此标记为已解决或已关闭吗?谢谢。
标签: php xml csv google-shopping