У меня проблемы с выяснением того, как правильно преобразовать список данных о товарах из XML в формат CSV.
Мой источник - это файл XML, содержащий список товаров с такими атрибутами, как цвет, размер, материал и т. Д.со следующей структурой:
<?xml version="1.0" encoding="utf-8" ?>
<store>
<products>
<product>
<name>T-Shirt</name>
<price>19.00</price>
<attributes>
<attribute>
<name>Color</name>
<options>
<option>
<name>White</name>
<price>0.00</price>
</option>
<option>
<name>Black</name>
<price>0.00</price>
</option>
<option>
<name>Blue</name>
<price>0.00</price>
</option>
</options>
</attribute>
<attribute>
<name>Size</name>
<options>
<option>
<name>XS</name>
<price>-5.00</price>
</option>
<option>
<name>S</name>
<price>-5.00</price>
</option>
<option>
<name>M</name>
<price>0.00</price>
</option>
<option>
<name>L</name>
<price>0.00</price>
</option>
<option>
<name>XL</name>
<price>5.00</price>
</option>
</options>
</attribute>
</attributes>
</product>
<product>
<name>Sweatshirt</name>
<price>49.00</price>
<attributes>
<attribute>
<name>Color</name>
<options>
<option>
<name>White</name>
<price>0.00</price>
</option>
<option>
<name>Black</name>
<price>0.00</price>
</option>
</options>
</attribute>
<attribute>
<name>Size</name>
<options>
<option>
<name>XS</name>
<price>-10.00</price>
</option>
<option>
<name>M</name>
<price>0.00</price>
</option>
<option>
<name>XL</name>
<price>10.00</price>
</option>
</options>
</attribute>
<attribute>
<name>Material</name>
<options>
<option>
<name>Cotton</name>
<price>10.00</price>
</option>
<option>
<name>Polyester</name>
<price>0.00</price>
</option>
</options>
</attribute>
</attributes>
</product>
<product>
<name>Earrings</name>
<price>29.00</price>
</product>
</products>
</store>
Каждый продукт имеет ряд элементов, таких как имя, цена и т. д., но также случайное количество атрибутов (таких как цвет, размер, материал и т. д.), которые также имеют случайныйколичество вариантов.Каждый вариант может повлиять на цену продукта, поэтому заказ футболки размера XS может быть дешевле, чем заказ футболки размера XL.
Я бы хотел, чтобы CSV представлял одну комбинацию атрибутов накаждая строка.
В моем примере это даст 3 цвета x 5 размеров = 15 линий для футболки, 2 цвета x 3 размера x 2 материала = 12 линий для толстовки и 1 строка для сережек без каких-либо атрибутов:
name,price,color,size,material
T-Shirt,14.00,White,XS,
T-Shirt,14.00,Black,XS,
T-Shirt,14.00,Blue,XS,
T-Shirt,14.00,White,S,
T-Shirt,14.00,Black,S,
T-Shirt,14.00,Blue,S,
T-Shirt,19.00,White,M,
T-Shirt,19.00,Black,M,
T-Shirt,19.00,Blue,M,
T-Shirt,19.00,White,L,
T-Shirt,19.00,Black,L,
T-Shirt,19.00,Blue,L,
T-Shirt,24.00,White,XL,
T-Shirt,24.00,Black,XL,
T-Shirt,24.00,Blue,XL,
Sweatshirt,49.00,White,XS,Cotton
Sweatshirt,49.00,Black,XS,Cotton
Sweatshirt,59.00,White,M,Cotton
Sweatshirt,69.00,Black,M,Cotton
Sweatshirt,69.00,White,XL,Cotton
Sweatshirt,69.00,Black,XL,Cotton
Sweatshirt,39.00,White,XS,Polyester
Sweatshirt,39.00,Black,XS,Polyester
Sweatshirt,49.00,White,M,Polyester
Sweatshirt,49.00,Black,M,Polyester
Sweatshirt,59.00,White,XL,Polyester
Sweatshirt,59.00,Black,XL,Polyester
Earrings,29.00,,,
Мне уже удалось создать выход CSV для простых продуктов, таких как серьги и продукты только с одним атрибутом, но я изо всех сил пытаюсь найти способ создания всех возможных комбинаций атрибутов продукта для продуктов сболее одного атрибута.
Мои жалкие попытки до сих пор привели к следующему коду:
<?php
mb_internal_encoding("UTF-8");
header('Content-Type: text/html; charset=utf-8');
$source = "example.xml";
$handle = fopen($source, "r");
$fp = fopen('export.csv', 'w');
$xml = simplexml_load_file($source);
// Generate list of attributes (for csv header etc.)
$header_attributes = array();
foreach ($xml->products->product as $product) {
if(isset($product->attributes)) {
foreach($product->attributes->attribute as $attribute) {
array_push($header_attributes, $attribute->name);
}
}
}
$header_attributes = array_unique($header_attributes);
$csvheader = array(
'name','price' // these exist for all products, could also include weight, image, description, special price etc...
);
$static_csvheadercount = count($csvheader);
foreach($header_attributes as $attribute) {
array_push($csvheader, $attribute); // add variable number of attribute fields to csv header
}
fputcsv($fp, $csvheader);
foreach ($xml->products->product as $product) { // loop through each product
if(isset($product->attributes)) $simple = 0;
else $simple = 1;
if($simple == 1) { // if product is a simple product with no attributes
$output=array();
array_push($output,(string)$product->name);
array_push($output,(string)$product->price);
for($i = $static_csvheadercount + $attribute_position; $i < count($csvheader); $i++) {
array_push($output, '');
}
fputcsv($fp, $output);
}
else { // is a configurable product with attributes
$json = json_encode($product->attributes);
$attributes = json_decode($json, TRUE);
$attributes_number = count($product->attributes->attribute);
if($attributes_number > 1) { // if product has more than 1 attributes so we have to generate each attribute combination
//
// I'm trying to figure out what should happen here
//
}
else { // if product has only one attribute
$attributename = (string)$product->attributes->attribute->name;
$attribute_position = array_search($attributename, $header_attributes);
$options_number = count($product->attributes->options->option);
$pos = 1;
foreach($attributes['attribute']['options']['option'] as $option) {
$output=array();
array_push($output,(string)$product->name);
array_push($output,(string)$product->price);
for($i = $static_csvheadercount - 1; $i < ($static_csvheadercount + $attribute_position); $i++) {
array_push($output, '');
}
$output[$static_csvheadercount + $attribute_position] = $option['name'];
for($i = $static_csvheadercount + $attribute_position; $i < count($csvheader) - 1 ; $i++) {
array_push($output, '');
}
fputcsv($fp, $output);
$pos++;
}
$output=array();
array_push($output,(string)$product->name);
array_push($output,(string)$product->price);
for($i = $static_csvheadercount; $i < count($csvheader); $i++) {
array_push($output, '');
}
fputcsv($fp, $output);
}
}
}
?>
Я застрял в этой проблеме в течение нескольких часов, не в состоянии найти решение.
Может кто-нибудь дать несколько советов или указателей, как добиться результата для продуктов с несколькими атрибутами?