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:----ZUzvJxOYKFreMGIQoAJZQBmtzdK08C8be3joasYBWBMA4c3PnVcyXzR3HF3wUItux/adpuJ9QrfbtCc4SBixuAd/Lr1qghjg3mL0GcE17FdxAI9+ztk8xdFx1ZPeSRmY1dmQG4UMYVHN9zOn64G11oh5J52O58eUzJtX5CVq9awOGF6QOVXzmWnR00zbqXe/E+8kaxEltUylgL4kp8D7nFLaVqbEo4D5o4pRUzQwqt2xi+xlpdPJWd2Nwa7qpXK98QIU9hor6UUjePzQpsqAVWlGcDa4Fjt1Hc7h5Rp2As8Ve+hae73QvmQ2E0h+i4ROjcSEQnwyGFDIfatIDP0Ja0On3KjAqWap+JdjR6hproEHELQ9XSgBQa0z9hBB+hC25H0RUsog7oBeXgHeGPSCgf59/Uog1zt+1Fv+YBeC7Lx/1Wb6AnTY0kaS088FF56dSaNjgNGfmzycINZ/ULcWGm30Vpyqmw8vXKQTQkBTXyZpeyomxZSPuJvSaBEiHbqThXql+Q2M8mLDvkR2K0gyR+ltGjC+OCchmju64B0LvhTzbS+BOn6TRn2nT7I1Qtx1nn86QdBXq5RbzEWhv0q/6FrR5amIXWVmN+M19LWqzQdUMmacjO+hBx6sB7AvkJRbSwjoOvhpqODu9aU6ZvzaD5p/NrjvC/U5FYwDvW3Fq0E=----ATTACHMENT:----Mjk4OTgzOTQxMzU5MjM5MiAxODA4NjQ0NTEyNDI2OTA0IDQxMzE2Nzk0Mzg0NzQzOQ==