Update XML writer to support writing root element text and attributes (the reverse of what Reader does).

This commit is contained in:
Buster Neece 2024-04-21 09:46:20 -05:00
parent 820cc7ad03
commit ba4a71cd98
No known key found for this signature in database
1 changed files with 25 additions and 33 deletions

View File

@ -8,7 +8,6 @@ declare(strict_types=1);
namespace App\Xml;
use RuntimeException;
use XMLWriter;
final class Writer
@ -29,9 +28,6 @@ final class Writer
$writer->startElement($baseElement);
// Make sure attributes come first
uksort($config, [self::class, 'attributesFirst']);
foreach ($config as $sectionName => $data) {
if (!is_array($data)) {
if (str_starts_with($sectionName, '@')) {
@ -55,54 +51,50 @@ final class Writer
array $config,
XMLWriter $writer
): void {
$branchType = null;
// Ensure attributes come first.
uksort($config, [self::class, 'attributesFirst']);
$attributes = [];
$innerText = null;
foreach ($config as $key => $value) {
if ($branchType === null) {
if (is_numeric($key)) {
$branchType = 'numeric';
} else {
$writer->startElement($branchName);
$branchType = 'string';
if (str_starts_with((string)$key, '@')) {
$attributes[substr($key, 1)] = (string)$value;
unset($config[$key]);
} else {
if ('_' === $key) {
$innerText = (string)$value;
unset($config[$key]);
}
} elseif ($branchType !== (is_numeric($key) ? 'numeric' : 'string')) {
throw new RuntimeException('Mixing of string and numeric keys is not allowed');
}
}
if ($branchType === 'numeric') {
if (0 !== count($config) && array_is_list($config)) {
foreach ($config as $value) {
if (is_array($value)) {
self::addBranch($branchName, $value, $writer);
} else {
$writer->writeElement($branchName, (string)$value);
}
} else {
}
} else {
$writer->startElement($branchName);
foreach ($attributes as $attrKey => $attrVal) {
$writer->writeAttribute($attrKey, $attrVal);
}
if (null !== $innerText) {
$writer->text($innerText);
}
foreach ($config as $key => $value) {
/** @var string $key */
if (is_array($value)) {
self::addBranch($key, $value, $writer);
} elseif (str_starts_with($key, '@')) {
$writer->writeAttribute(substr($key, 1), (string)$value);
} else {
$writer->writeElement($key, (string)$value);
}
}
}
if ($branchType === 'string') {
$writer->endElement();
}
}
private static function attributesFirst(mixed $a, mixed $b): int
{
if (str_starts_with((string)$a, '@')) {
return -1;
}
if (str_starts_with((string)$b, '@')) {
return 1;
}
return 0;
}
}