* @phpstan-impure * @internal The actual returned class is Generator (undocumented) */ private function iterateNonReservedNamespaces(DOMDocument $document): Generator { $xpath = new DOMXPath($document); $namespaceNodes = $xpath->query('//namespace::*') ?: new DOMNodeList(); foreach ($namespaceNodes as $namespaceNode) { // discard removed namespaces they could be returned by XPath if (null === $namespaceNode->namespaceURI) { continue; } // discard reserved (internal xml) namespaces if ($this->isNamespaceReserved($namespaceNode->namespaceURI)) { continue; } yield $namespaceNode; } } /** * @param DOMNode&object $namespaceNode */ private function removeNamespaceNodeAttribute($namespaceNode): void { $ownerElement = $namespaceNode->parentNode; if ($ownerElement instanceof DOMElement) { $localName = ('xmlns' === $namespaceNode->localName) ? '' : (string) $namespaceNode->localName; if ($ownerElement->hasAttributeNS(XmlConstants::NAMESPACE_XMLNS, $localName)) { $ownerElement->removeAttributeNS((string) $namespaceNode->nodeValue, $localName); } } } private function isNamespaceReserved(string $namespace): bool { $reservedNameSpaces = [ XmlConstants::NAMESPACE_XML, // xml XmlConstants::NAMESPACE_XMLNS, // xml namespace allocation XmlConstants::NAMESPACE_XSI, // xml schema instance ]; return in_array($namespace, $reservedNameSpaces, true); } private function isNamespaceRelatedToSat(string $namespace): bool { return str_starts_with($namespace, 'http://www.sat.gob.mx/'); } }