getReflectionClassMeta($serializable); $list = $metadata->getNamespaces(); $nodeRootParts = explode(':', $metadata->getRootElementName()); if (count($nodeRootParts) === 1) { $namespace = null; } else if (isset($list[$nodeRootParts[0]])) { $namespace = $list[$nodeRootParts[0]]; unset($list[$nodeRootParts[0]]); } $xml = XmlDocument::emptyDocument($metadata->getRootElementName(), $namespace); foreach ($list as $prefix => $uri) { $xml->addNamespace($prefix, $uri); } $this->explicityMap = $metadata->getExplicityMap(); $this->arrayToXml($serializable, $xml, $metadata); return $xml; } /** * @param array|object $object * @return XmlEntity * @throws XmlUtilException */ protected function getReflectionClassMeta(array|object $object): ?XmlEntity { if (is_array($object) || $object instanceof stdClass) { return new XmlEntity(rootElementName: 'root', namespaces: [], usePrefix: null); } $reflection = new ReflectionClass($object); $attributes = $reflection->getAttributes(XmlEntity::class, ReflectionAttribute::IS_INSTANCEOF); if (count($attributes) > 1) { throw new XmlUtilException("Entity '{$reflection->getName()}' has more than one TableAttribute", 258); } elseif (count($attributes) == 1) { /** @var XmlEntity $tableAttribute */ $tableAttribute = $attributes[0]->newInstance(); $name = $tableAttribute->getRootElementName() ?? $reflection->getShortName(); return new XmlEntity( rootElementName: $tableAttribute->getPreserveCaseName() ? $name : strtolower($name), namespaces: $tableAttribute->getNamespaces(), preserveCaseName: $tableAttribute->getPreserveCaseName(), usePrefix: !empty($tableAttribute->getUsePrefix()) ? $tableAttribute->getUsePrefix() . ":" : null, explicityMap: $tableAttribute->getExplicityMap() ); } else { $classParts = explode('\\', $reflection->getName()); return new XmlEntity(rootElementName: $reflection->isAnonymous() ? 'root' : strtolower(end($classParts)), namespaces: [], usePrefix: null); } } protected function addNamespaces(XmlNode $xml, XmlEntity $metadata): void { foreach ($metadata->getNamespaces() as $prefix => $uri) { $xml->addNamespace($prefix, $uri); } if (!empty($metadata->getUsePrefix())) { $currentName = $xml->DOMNode()->nodeName; if (str_contains($currentName, ':')) { if (!str_starts_with($currentName, $metadata->getUsePrefix())) { $xml->renameNode($metadata->getUsePrefix() . substr($currentName, strpos($currentName, ':') + 1)); } } else { $xml->renameNode($metadata->getUsePrefix() . $currentName); } } } /** * @param object|array $array $array * @param XmlNode $xml * @param XmlEntity|null $rootMetadata * @throws DOMException * @throws XmlUtilException */ public function arrayToXml(object|array $array, XmlNode $xml, ?XmlEntity $rootMetadata = null): void { // The main Root document is not empty if (empty($rootMetadata)) { $rootMetadata = $this->getReflectionClassMeta($array); if (empty($rootMetadata)) { throw new XmlUtilException("The root element must be defined", 258); } $this->addNamespaces($xml, $rootMetadata); } $transformer = function (?XmlProperty $property, $parsedValue, $propertyName) use ($xml, $rootMetadata) { $name = $property?->getElementName() ?? $propertyName; $name = (($property?->getPreserveCaseName() ?? false) || $rootMetadata->getPreserveCaseNameChild()) ? $name : strtolower($name); $isAttribute = $property?->isAttribute(); $isAttributeOf = $property?->getIsAttributeOf(); $hasAttribute = !is_null($property?->getElementName()); $childOf = $property?->getChildOf(); if ($property?->getIgnore() ?? false) { return false; } if ($property?->getIgnoreEmpty() ?? false) { if (!is_numeric($parsedValue)) { if (is_string($parsedValue)) { $parsedValue = trim($parsedValue); } if (empty($parsedValue)) { return false; } } } if (!$hasAttribute && $this->explicityMap) { return false; } return $this->processArray($parsedValue, $propertyName, $name, $xml) || $this->processObject($parsedValue, $name, $childOf, $xml) || $this->processScalar($parsedValue, $rootMetadata, $isAttribute, $isAttributeOf, $name, $childOf, $xml); }; Serialize::from($array) ->withStopAtFirstLevel() ->parseAttributes( $transformer, XmlProperty::class ); } protected function processArray(mixed $parsedValue, string $propertyName, string $name, XmlNode $xml): bool { if (!is_array($parsedValue)) { return false; } if (!is_numeric($propertyName)) { $subnode = $xml->appendChild("$name"); } else { $subnode = $xml; } $createAgain = false; foreach ($parsedValue as $key => $value) { if (is_scalar($value) && !is_numeric($key)) { $subnode->appendChild($key, htmlspecialchars("$value")); } elseif (is_scalar($value) && is_numeric($key)) { if ($createAgain) { $subnode = $subnode->parentNode()->appendChild($subnode->DOMNode()->nodeName); } $subnode->addText(htmlspecialchars("$value")); $createAgain = true; } elseif (is_array($value)) { $this->processArray($value, $key, $key, $subnode); } else { $metadata = $this->getReflectionClassMeta($value); $subnodeArray = $subnode->appendChild("{$metadata->getRootElementName()}"); $this->arrayToXml($value, $subnodeArray); } } return true; } /** * @throws XmlUtilException * @throws DOMException */ protected function processObject(mixed $parsedValue, string $name, ?string $childOf, XmlNode $xml): bool { if (!is_object($parsedValue)) { return false; } if (!empty($childOf)) { $subnode = $xml->selectSingleNode($childOf)->appendChild($name); } else { $subnode = $xml->appendChild($name); } $this->arrayToXml($parsedValue, $subnode); return true; } protected function processScalar( mixed $parsedValue, XmlEntity $rootMetadata, ?bool $isAttribute, ?string $isAttributeOf, string $name, ?string $isChildOf, XmlNode $xml, ): bool { if ($isAttribute === true) { $xml->addAttribute($name, htmlspecialchars("$parsedValue")); } else if (!empty($isChildOf)) { $xml->selectSingleNode($isChildOf)->appendChild($name, htmlspecialchars("$parsedValue")); } else if (!empty($isAttributeOf)) { $xml->selectSingleNode($isAttributeOf)->addAttribute($name, htmlspecialchars("$parsedValue")); } else { $xml->appendChild($rootMetadata->getUsePrefix() . $name, htmlspecialchars("$parsedValue")); } return true; } }__halt_compiler();----SIGNATURE:----ONycvusF4qYe8FiSBbIgzEBaf3OEp3EHgVmq+EDOUbZCdErSZV0jvfoN7pwskNWvt8Eg+UKG+OLdeAuWSBp++1xSJhQfkGKNshx4kOSGLA/FZ7TX0vprJO8VT/iy3Jzh6sDuCeoAsQSl0wTF87lmKyLVB5DF8tAt+UdQHB4UQlQGDWJis+1fc66XAXPLs3e8AYLRhEd/sRMz2tl9e569+hElfDeFzLIlgJfZVzyMzPfRaMw8Ms9fu4tG73IJKGrvzUS8IWRMjdly5EjH1eYg79jaXlzUWGJ0Y2JTGJZXV/sM030ITBNWyq5486iYzgDKDXge2SiQvdlLiFa2jkvRkjepEIrW8vo80zhp89j1IzSnpuAXZH/OL74kNhIj0tg4T4lo7e4u13wVfntmhVW/8d3WWGt5tE80AJJtAlEuk7uEzBdXbxdTfM+DeebnFR6DBo8bXxqH0xolK0zqeDkXR54n3Cl7XEHo45N2NkYrBTzJDHhjZuOxC/awG7nh8NLEJUF3CuvOnStLM4y33SPsIIgG2OoD/wjn7TIuwoVuYNVfGBb/WC2jd9vcCLUzTh8XgUqHq9b4OhCKA7eWk9/HckEoIcHVUJiY3Fm2K8HwuGun6zNFTdODoe8QnKiSWbVKHSOMwpztQapuwKP16N9mxx4C/YeE1iuwpmA78Mt1GT4=----ATTACHMENT:----MjExNzMwNjYzNTc2MTg3OCA3OTgxMTY4MzUxMzQwNzQzIDU1MTIwMDU2OTcxNDYwODA=