Разбор XML со связанными мульти-значениями

У меня есть XML как:

<?xml version="1.0" encoding="UTF-8"?>
<shop>
<categories>
<category id="310" parent_id="305" title="PHILIPS"/>
<category id="305" parent_id="233" title="LED TV"/>
<category id="233" parent_id="0" title="Television" title_ru="cat1 ru" title_en="cat1 en"/>

<category id="525" parent_id="435" title="Manufacturer"/>
<category id="396" parent_id="0" title="Parrent categgory"/>
<category id="435" parent_id="396" title="Sub category"/>
</categories>
<products>
<product id="807" category_id="525" code="1002" price="3.95" count="99" name="Product 1"/>
<product id="2002" category_id="525" code="EFG 90750X" price="99" count="0" name="Product 2"/>
<product id="2691" category_id="525" code="L 87695WD" price="99" count="1" name="Product 3"/>
<product id="2909" category_id="525" code="ZEI 6240FBA" price="99" count="0" name="Product 4"/>
<product id="3532" category_id="525" code="HK 654400XB" price="99" count="0" name="Product 5"/>
<product id="4150" category_id="310" code="24PHH4109/88" price="99" is_featured="1" count="&gt;10" name="Product 6"/>
<product id="4378" category_id="310" code="22PFK4209/12" price="99" is_featured="1" count="&gt;10" name="Product 7"/>
<product id="4065" category_id="310" code="22PFH4109/88" price="99" is_featured="1" count="&gt;10" name="Product 8"/>
<product id="4080" category_id="310" code="20PHH4109/88" price="99" is_featured="1" count="&gt;10" name="Product 9"/>
</products>
</shop>

Я могу разобрать «продукты» по коду:

$url = "code.xml";
$xml = simplexml_load_file($url);

foreach($xml->products->product as $product) {

echo
'"L_'.$product[0]['code'].'_'.$product[0]['id'].
'"^"'.$product[0]['name'].
'"^"'.$product[0]['category_id'].
'"^"0.01"^^^^^'
.'"'.$product[0]['code'].'"'.
"\n";
}

Но в этом случае я не получаю значения «Производитель», «Категория Parrent» и «Подкатегория», как его можно проанализировать?

-2

Решение

Одним из способов было бы использовать XPath запрос на ваш объект XML:

$url = "code.xml";
$xml = simplexml_load_file($url);

foreach ($xml->products->product as $product) {
// Get categories
$categoryId           = $product['category_id'];
list($category)       = $xml->xpath("//category[@id=$categoryId]");

$subCategoryId        = $category['parent_id'];
list($subCategory)    = $xml->xpath("//category[@id=$subCategoryId]");

$parentCategoryId     = $subCategory['parent_id'];
list($parentCategory) = $xml->xpath("//category[@id=$parentCategoryId]");

// Show categories
echo "Category:        ", $category['title'], PHP_EOL;
echo "Sub category:    ", $subCategory['title'], PHP_EOL;
echo "Parent category: ", $parentCategory['title'], PHP_EOL;

// Same as before
echo
'"L_'.$product[0]['code'].'_'.$product[0]['id'].
'"^"'.$product[0]['name'].
'"^"'.$product[0]['category_id'].
'"^"0.01"^^^^^'
.'"'.$product[0]['code'].'"'.
"\n";
}

Выход:

Category:        Manufacturer
Sub category:    Sub category
Parent category: Parrent categgory
"L_1002_807"^"Product 1"^"525"^"0.01"^^^^^"1002"Category:        Manufacturer
Sub category:    Sub category
Parent category: Parrent categgory
"L_EFG 90750X_2002"^"Product 2"^"525"^"0.01"^^^^^"EFG 90750X"...
Category:        PHILIPS
Sub category:    LED TV
Parent category: Television
"L_20PHH4109/88_4080"^"Product 9"^"310"^"0.01"^^^^^"20PHH4109/88"
0

Другие решения

XPath — это путь. Но вам нужно разделить задачи. Вызов одного и того же кода для «пронумерованных» переменных (или использование нескольких префиксов, таких как: sub, parent) является хорошим знаком того, что вы должны использовать цикл.

В этом случае цикл, который выбирает данные категории, пока он получает родительский идентификатор, который больше нуля.

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);

function getCategories($xpath, $id) {
$result = [];
do {
$categories = $xpath->evaluate('/shop/categories/category[@id = "'.$id.'"]');
if ($category = $categories->item(0)) {
$result[$id] = [
'id' => $id,
'title' => $category->getAttribute('title')
];
$id = $category->getAttribute('parent_id');
} else {
break;
}
} while ($id > 0);
return $result;
}

$result = [];
foreach ($xpath->evaluate('//product') as $product) {
$result[] = [
'name' => $product->getAttribute('name'),
'categories' => getCategories($xpath, $product->getAttribute('category_id'))
];
}
var_dump($result);

Выход:

array(9) {
[0]=>
array(2) {
["name"]=>
string(9) "Product 1"["categories"]=>
array(3) {
[525]=>
array(2) {
["id"]=>
string(3) "525"["title"]=>
string(12) "Manufacturer"}
[435]=>
array(2) {
["id"]=>
string(3) "435"["title"]=>
string(12) "Sub category"}
[396]=>
array(2) {
["id"]=>
string(3) "396"["title"]=>
string(17) "Parrent categgory"}
}
}
[1]=>
array(2) {
["name"]=>
string(9) "Product 2"["categories"]=>
array(3) {
[525]=>
array(2) {
["id"]=>
string(3) "525"["title"]=>
string(12) "Manufacturer"}
...
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector