From 1da822f0090934ff9551c83298195426a10477c5 Mon Sep 17 00:00:00 2001 From: Alex Tartan Date: Sun, 29 Sep 2019 15:14:16 +0300 Subject: [PATCH] Add conversion option --- README.md | 13 +++++----- src/ArrayToXml/XmlToArray.php | 20 ++++++++++++--- src/ArrayToXml/XmlToArrayConfig.php | 39 ++++++++++++++++++----------- test/ArrayToXml/XmlToArrayTest.php | 31 +++++++++++++++++++++++ 4 files changed, 79 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 37b38dc..b0e5747 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,13 @@ Convert an XML (either DOMDocument or string) to an array // default value: $config = [ - 'version' => '1.0', - 'encoding' => 'UTF-8', - 'attributesKey' => '@attributes', - 'cdataKey' => '@cdata', - 'valueKey' => '@value', - 'useNamespaces' => false, + 'version' => '1.0', + 'encoding' => 'UTF-8', + 'attributesKey' => '@attributes', + 'cdataKey' => '@cdata', + 'valueKey' => '@value', + 'useNamespaces' => false, + 'forceOneElementArray => false, ]; $xtoa = new XmlToArray($config); diff --git a/src/ArrayToXml/XmlToArray.php b/src/ArrayToXml/XmlToArray.php index 27528ae..cfe908f 100644 --- a/src/ArrayToXml/XmlToArray.php +++ b/src/ArrayToXml/XmlToArray.php @@ -24,6 +24,16 @@ use DOMElement; use DOMNode; use LibXMLError; +use function array_key_exists; +use function is_array; +use function is_string; +use function libxml_clear_errors; +use function libxml_get_last_error; +use function libxml_use_internal_errors; +use function trim; +use const XML_CDATA_SECTION_NODE; +use const XML_ELEMENT_NODE; +use const XML_TEXT_NODE; /** * This class helps convert an XML to an array @@ -190,10 +200,12 @@ private function normalizeValues($output) return $output; } - // if only one node of its kind, assign it directly instead if array($value); - foreach ($output as $key => $value) { - if (is_array($value) && count($value) === 1) { - $output[$key] = $value[0]; + if (!$this->config->isForceOneElementArray()) { + // if only one node of its kind, assign it directly instead if array($value); + foreach ($output as $key => $value) { + if (is_array($value) && count($value) === 1) { + $output[$key] = $value[0]; + } } } diff --git a/src/ArrayToXml/XmlToArrayConfig.php b/src/ArrayToXml/XmlToArrayConfig.php index 7c5d748..5ed5a90 100644 --- a/src/ArrayToXml/XmlToArrayConfig.php +++ b/src/ArrayToXml/XmlToArrayConfig.php @@ -3,15 +3,18 @@ namespace AlexTartan\Array2Xml; +use function array_merge; + final class XmlToArrayConfig { private const DEFAULTS = [ - 'version' => '1.0', - 'encoding' => 'UTF-8', - 'attributesKey' => '@attributes', - 'cdataKey' => '@cdata', - 'valueKey' => '@value', - 'useNamespaces' => false, + 'version' => '1.0', + 'encoding' => 'UTF-8', + 'attributesKey' => '@attributes', + 'cdataKey' => '@cdata', + 'valueKey' => '@value', + 'useNamespaces' => false, + 'forceOneElementArray' => false, ]; /** @var string */ @@ -38,14 +41,16 @@ private function __construct( string $attributesKey, string $cdataKey, string $valueKey, - bool $useNamespaces + bool $useNamespaces, + bool $forceOneElementArray ) { - $this->version = $version; - $this->encoding = $encoding; - $this->attributesKey = $attributesKey; - $this->cdataKey = $cdataKey; - $this->valueKey = $valueKey; - $this->useNamespaces = $useNamespaces; + $this->version = $version; + $this->encoding = $encoding; + $this->attributesKey = $attributesKey; + $this->cdataKey = $cdataKey; + $this->valueKey = $valueKey; + $this->useNamespaces = $useNamespaces; + $this->forceOneElementArray = $forceOneElementArray; } public static function fromArray(array $configData = []): self @@ -58,7 +63,8 @@ public static function fromArray(array $configData = []): self $config['attributesKey'], $config['cdataKey'], $config['valueKey'], - (bool)$config['useNamespaces'] + (bool)$config['useNamespaces'], + (bool)$config['forceOneElementArray'] ); } @@ -91,4 +97,9 @@ public function isUseNamespaces(): bool { return $this->useNamespaces; } + + public function isForceOneElementArray(): bool + { + return $this->forceOneElementArray; + } } diff --git a/test/ArrayToXml/XmlToArrayTest.php b/test/ArrayToXml/XmlToArrayTest.php index 232b3b3..05f7efe 100644 --- a/test/ArrayToXml/XmlToArrayTest.php +++ b/test/ArrayToXml/XmlToArrayTest.php @@ -7,6 +7,7 @@ use AlexTartan\Array2Xml\XmlToArray; use DOMDocument; use PHPUnit\Framework\TestCase; +use function implode; final class XmlToArrayTest extends TestCase { @@ -307,4 +308,34 @@ public function testXmlWithEmptyNodes(): void $output ); } + + public function testXmlWithForceOneElementNodes(): void + { + $doc = new DOMDocument('1.0', 'UTF-8'); + $doc->loadXML( + implode( + '', + [ + '', + 'sd', + '80', + '120', + '
', + ] + ) + ); + + $output = (new XmlToArray(['forceOneElementArray' => true]))->buildArrayFromDomDocument($doc); + + self::assertSame( + [ + 'table' => [ + 'name' => ['sd'], + 'width' => ['80'], + 'length' => ['120'], + ], + ], + $output + ); + } }