@kolomat

Как добавить в ассоциативный массив значение attributes() эллемента xml?

Добрый день, возможно неправильно поставлен вопрос, не судите строго. Суть проблема следующая, есть вполне стандартный xml документ
<offer id="129" available="true" >
<url>http://api.loc/index.php?route=product/product&amp;path=3899&amp;product_id=131</url>
<price>850</price>
<currencyId>UAH</currencyId>
<categoryId>3899</categoryId>
<delivery>true</delivery>
<stock_quantity>100</stock_quantity>
<name>Босоножки 82BLUE р. 26 17 см Синий</name>
<vendor>(производитель не указан)</vendor>
<barcode>200</barcode>
<param name="Размер">26</param>
<param name="Размер стельки">12</param>
</offer>
<offer id="130" available="true" >
<url>http://api.loc/index.php?route=product/product&amp;path=3899&amp;product_id=130</url>
<price>850</price>
<currencyId>UAH</currencyId>
<categoryId>3899</categoryId>
<delivery>true</delivery>
<stock_quantity>100</stock_quantity>
<name>Босоножки 82BLUE р. 27 17,5 см Синий</name>
<vendor>(производитель не указан)</vendor>
<barcode>200</barcode>
<param name="Размер обуви">46</param>
<param name="Размер стельки">19</param>
</offer>

Хочу создать ассоциативный массив такого плана
[0] => Array
        (
            [id] => 200
            [razmer] => 26
            [stelka] => 12
        )
    [1] => Array
        (
            [id] => 200
            [razmer] => 46
            [stelka] => 19
        )

Пытаюсь сделать так
$join = [];
	foreach($xml->shop->offers->offer as $offer)
	{
	$id = (string)$offer->barcode;
	
		$join[$k] = [
			'id' => $id,
			'razmer' => (string) $offer->param[0],
			'stelka' => (string) $offer->param[1]
		];
		$k++;
	}

Но при распечатке массива $join получается так
[] => Array
        (
            [id] => 200
            [razmer] => 46
            [stelka] => 19
        )

Но проблема состоит в том что в массив $join добавляется не все офферы из xml, а только последний. В чем может быть проблема и что я неправильно сделал?
P.S. Извеняюсь, вопрос закрыт, банальная ошибка в синтаксисе))
  • Вопрос задан
  • 58 просмотров
Решения вопроса 1
Maksclub
@Maksclub Куратор тега PHP
maksfedorov.ru
Когда вы превращает документа в SimpleXMLElement, то каждая дочернаяя нода тоже таковой становится и у нее также есть свой набор атрибуттов $element->attributes()
Итоговый код

<?php

$string = <<<XML
<offer id="130" available="true" >
<url>http://api.loc/index.php?route=product/product&amp;path=3899&amp;product_id=130</url>
<price>850</price>
<currencyId>UAH</currencyId>
<categoryId>3899</categoryId>
<delivery>true</delivery>
<stock_quantity>100</stock_quantity>
<name>Босоножки 82BLUE р. 27 17,5 см Синий</name>
<vendor>(производитель не указан)</vendor>
<barcode>200</barcode>
<param name="Размер обуви">46</param>
<param name="Размер стельки">19</param>
</offer>
XML
;

$xml = new SimpleXMLElement($string);

$params = [];
// Все ноды с тегом param ушли в массив, каждый из из которых  SimpleXMLElement
foreach($xml->param as $param) {
    // а также @attributes, в котором все атрибуты текущего элемента, достаем тот, что name
    $paramName = $param->attributes()['name'];
    $params[(string) $paramName] = (string) $param;
}

var_dump($params);
// [
//     "Размер обуви"   => string(2) "46"
//     "Размер стельки" => string(2) "19
// ]


UPD: Чтобы руками все не писать и не гадать, какой параметр пришел каким по счету (а могут прийти в одной выгрузке в разном порядке из-за того, что у одного товара просто не указан один из параметров, то предлагаю сделать так:

1. Завести карту всех соответствий
$featuresMap = [
    'Размер обуви' => 'size',
    'Размер стельки' => 'stelka',
];

2. И уже динамически собирать с каждого элемента по этой карте параметры
foreach($xml->param as $param) {
    $paramName = $param->attributes()['name'];
    $paramAlias = $featuresMap[(string) $paramName]
    $params[$paramAlias] = (string) $param;
}


И тогда вам нужно будет только расширять свою карту соответствий, а код цикла всегда будет оставаться одним и тем же. Ну добавив пару проверок и например транслитерировать новые значения, добавляя их в БД, и карту уже брать из той же БД.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы