Skip to content

Commit e5fe0c9

Browse files
committed
Flatten array without root node name
1 parent 2406405 commit e5fe0c9

File tree

5 files changed

+52
-3
lines changed

5 files changed

+52
-3
lines changed

src/Formatter/BaseConfig.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,9 @@ public function getFlattenAttributes(): string
7979
{
8080
return self::FLATTEN_ATTRIBUTES;
8181
}
82+
83+
public function isWithoutRoot(): bool
84+
{
85+
return false;
86+
}
8287
}

src/Formatter/Config.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,6 @@ public function isFlatten(): bool;
2828
public function getFlattenNodes(): string;
2929

3030
public function getFlattenAttributes(): string;
31+
32+
public function isWithoutRoot(): bool;
3133
}

src/Formatter/FlattenConfig.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public function __construct(
1414
bool $autoCast = false,
1515
private ?string $flattenNodes = null,
1616
private ?string $flattenAttributes = null,
17+
private bool $withoutRoot = false,
1718
) {
1819
parent::__construct($alwaysArray, $autoCast);
1920
}
@@ -37,4 +38,9 @@ public function getFlattenAttributes(): string
3738
{
3839
return $this->flattenAttributes ?? parent::getFlattenAttributes();
3940
}
41+
42+
public function isWithoutRoot(): bool
43+
{
44+
return $this->withoutRoot;
45+
}
4046
}

src/Formatter/Formatter.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use function is_bool;
1515
use function is_numeric;
1616
use function is_scalar;
17+
use function ltrim;
1718
use function rtrim;
1819
use function sprintf;
1920
use function str_starts_with;
@@ -98,6 +99,11 @@ public static function decodeValue(mixed $value): mixed
9899
* @return mixed
99100
*/
100101
public static function nodeToArray(DOMNode $node, Config $config): mixed
102+
{
103+
return self::nodeToArrayRecursive($node, $config, 1);
104+
}
105+
106+
private static function nodeToArrayRecursive(DOMNode $node, Config $config, int $depth): mixed
101107
{
102108
$value = null;
103109
/** @var array<string,mixed> $attributes */
@@ -127,9 +133,9 @@ public static function nodeToArray(DOMNode $node, Config $config): mixed
127133
continue;
128134
}
129135

130-
$childNodes = self::nodeToArray($child, $config);
136+
$childNodes = self::nodeToArrayRecursive($child, $config, $depth + 1);
131137
if ($config->isFlatten()) {
132-
self::flattenArray($nodes, $child->nodeName, $childNodes, $config);
138+
self::flattenArray($nodes, $config->isWithoutRoot() && $depth === 1 ? '' : $child->nodeName, $childNodes, $config);
133139
} else {
134140
$nodes[$child->nodeName][] = $childNodes;
135141
}
@@ -173,7 +179,7 @@ private static function flattenArray(array &$nodes, string $nodeNames, mixed $ch
173179
} elseif ($childNodeName === $config->getValueName()) {
174180
$nodes[$nodeNames][] = $childNodeValues;
175181
} else {
176-
$nodeKey = sprintf('%s%s%s', $nodeNames, $config->getFlattenNodes(), $childNodeName);
182+
$nodeKey = ltrim(sprintf('%s%s%s', $nodeNames, $config->getFlattenNodes(), $childNodeName), $config->getFlattenNodes());
177183
if (is_array($childNodeValues)) {
178184
$nodes[$nodeKey] = array_merge($nodes[$nodeKey] ?? [], $childNodeValues);
179185
} else {

tests/Builder/NodeToArrayTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,36 @@ public function testWithFlattenConfig(): void
528528
);
529529
}
530530

531+
public function testWithFlattenWithoutRootConfig(): void
532+
{
533+
$xml = $this->newDocument();
534+
535+
$aE = $xml->addElement('a', [
536+
'version' => '1.0',
537+
]);
538+
$bE = $aE->addElement('b');
539+
$bE->addTextElement('c1', 1, ['test' => true, 'a' => 1.4]);
540+
$bE->addTextElement('c2', false);
541+
$bE->addTextElement('c3', 'test');
542+
$bE = $aE->addElement('b');
543+
$bE->addTextElement('c1', 0, ['test' => 'cc', 'b' => 2]);
544+
545+
$config = new FlattenConfig(withoutRoot: true);
546+
547+
self::assertSame(
548+
[
549+
'b/c1@test' => ['true', 'cc'],
550+
'b/c1@a' => '1.4',
551+
'b/c1' => ['1', '0'],
552+
'b/c2' => 'false',
553+
'b/c3' => 'test',
554+
'b/c1@b' => '2',
555+
'@version' => '1.0',
556+
],
557+
$xml->toArray($config),
558+
);
559+
}
560+
531561
public function testWithFlattenAutocastConfig(): void
532562
{
533563
$xml = $this->newDocument();

0 commit comments

Comments
 (0)