protected function _specialCasesToHandleString(XmlElement $xml) { return implode('^', $xml->children()); }
/** * Extends one node * * @param \Magento\Framework\Simplexml\Element $source * @param boolean $overwrite * @return $this * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function extendChild($source, $overwrite = false) { // this will be our new target node $targetChild = null; // name of the source node $sourceName = $source->getName(); // here we have children of our source node $sourceChildren = $source->children(); if (!$source->hasChildren()) { // handle string node if (isset($this->{$sourceName})) { // if target already has children return without regard if ($this->{$sourceName}->hasChildren()) { return $this; } if ($overwrite) { unset($this->{$sourceName}); } else { return $this; } } $targetChild = $this->addChild($sourceName, $source->xmlentities()); $targetChild->setParent($this); foreach ($source->attributes() as $key => $value) { $targetChild->addAttribute($key, $this->xmlentities($value)); } return $this; } if (isset($this->{$sourceName})) { $targetChild = $this->{$sourceName}; } if (is_null($targetChild)) { // if child target is not found create new and descend $targetChild = $this->addChild($sourceName); $targetChild->setParent($this); foreach ($source->attributes() as $key => $value) { $targetChild->addAttribute($key, $this->xmlentities($value)); } } // finally add our source node children to resulting new target node foreach ($sourceChildren as $childKey => $childNode) { $targetChild->extendChild($childNode, $overwrite); } return $this; }
/** * Этот метод разработал сам, но не тестировал, * потому что после разработки только заметил, * что применять его к стандартным файлам XML (@see Mage::getConfig()) всё равно нельзя: * в стандартном мега-файле, возвращаемом Mage::getConfig(), * одноимённые дочерние узлы уже отсутствуют (перетёрты друг другом). * * Отличие от стандартного метода @see asArray(): * если дерево XML содержит несколько одноимённых дочерних узлов, * то родительский метод при конвертации дерева XML в массив * перетирает содержимое дочерних узлов друг другом: * @see \Magento\Framework\Simplexml\Element::_asArray(): * $result[$childName] = $child->_asArray($isCanonical); * Например, дерево XML <url> <demo>http://fortis.magento-demo.ru/default/</demo> <demo>http://fortis.magento-demo.ru/second/</demo> <demo>http://fortis.magento-demo.ru/third/</demo> <demo>http://fortis.magento-demo.ru/fourth/</demo> <demo>http://fortis.magento-demo.ru/fifth/</demo> <demo_images_base>http://fortis.infortis-themes.com/demo/</demo_images_base> <forum>http://magento-forum.ru/forum/350/</forum> <official_site>http://themeforest.net/item/fortis-responsive-magento-theme/1744309?ref=dfediuk</official_site> </url> * будет сконвертировано в такой массив: [url] => Array ( [demo] => http://fortis.magento-demo.ru/fifth/ [demo_images_base] => http://fortis.infortis-themes.com/demo/ [forum] => http://magento-forum.ru/forum/350/ [official_site] => http://themeforest.net/item/fortis-responsive-magento-theme/1744309?ref=dfediuk ) * Обратите внимание, что содержимым ключа «demo» массива * стало содержимое последнего (по порядку следования) дочернего узла исходного дерева XML: <demo>http://fortis.magento-demo.ru/fifth/</demo> * * Наш метод @see asMultiArray() * при наличии в исходном дереве XML нескольких одноимённых дочерних узлов * добавляет их все в массив, создавая подмассив: [url] => Array ( [demo] => Array ( [0] => http://fortis.magento-demo.ru/default/ [1] => http://fortis.magento-demo.ru/second/ [2] => http://fortis.magento-demo.ru/third/ [3] => http://fortis.magento-demo.ru/fourth/ [4] => http://fortis.magento-demo.ru/fifth/ ) [demo_images_base] => http://fortis.infortis-themes.com/demo/ [forum] => http://magento-forum.ru/forum/350/ [official_site] => http://themeforest.net/item/fortis-responsive-magento-theme/1744309?ref=dfediuk ) * * @param MX $e * @param bool $isCanonical [optional] * @return array(string => string|array()) */ public static function asMultiArray(MX $e, $isCanonical = true) { /** @var array(string => string|array()) $result */ $result = []; if (!$e->hasChildren()) { /** Просто повторяем алгоритм метода @see \Magento\Framework\Simplexml\Element::_asArray() */ $result = $e->_asArray($isCanonical); } else { if (!$isCanonical) { /** Просто повторяем алгоритм метода @see \Magento\Framework\Simplexml\Element::_asArray() */ foreach ($e->attributes() as $attributeName => $attribute) { /** @var string $attributeName */ /** @var MX $attribute */ if ($attribute) { $result['@'][$attributeName] = (string) $attribute; } } } else { /** * Обратите внимание, что, * в отличие от метода @see \Magento\Framework\Simplexml\Element::_asArray(), * мы не можем использовать синтаксис * foreach ($e->children() as $childName => $child) { * потому что при таком синтаксисе мы не сможем получить доступ * ко всем одноимённым дочерним узлам. */ foreach ($e->children() as $child) { /** @var MX $child */ /** @var string $childName */ $childName = $child->getName(); /** @var array(string => string|array()) $childAsArray */ $childAsArray = self::asMultiArray($child, $isCanonical); if (!isset($result[$childName])) { /** * Просто повторяем алгоритм метода * @see \Magento\Framework\Simplexml\Element::_asArray() */ $result[$childName] = $childAsArray; } else { // у нас уже есть дочерний узел с данным именем if (!is_array($result[$childName])) { // преобразуем узел в массив $result[$childName] = [$result[$childName]]; } $result[$childName][] = $childAsArray; } } } } return $result; }