query_provider === null) { $this->query_provider = new DOMXPath($this); } if ($this->smart_query_cache[$query] ?? null) { //dump("Repeat"); return $this->smart_query_cache[$query]; } $retval = $this->query_provider->query($query); $this->smart_query_cache[$query] = $retval; return $retval; } /** * stripComments * * @return MyDOMDocument */ public function stripComments(): MyDOMDocument { $xpath = new DOMXPath($this); $comments = $xpath->query('//comment()'); foreach ($comments as $comment) { $comment->parentNode->removeChild($comment); } return $this; } /** * Load includes in XML Schema * * @return MyDOMDocument */ public function loadIncludes(array &$paths = []): MyDOMDocument { $query = "//*[local-name()='include']"; $xpath = new \DOMXPath($this); if ($xpath->query($query)->length > 0) { $this->loadExt($xpath->query($query), $paths); } return $this; } /** * Load imports * * @return MyDOMDocument */ public function loadImports(array &$paths = []): MyDOMDocument { $query = "//*[local-name()='import']"; $xpath = new \DOMXPath($this); if ($xpath->query($query)->length > 0) { $this->loadExt($xpath->query($query), $paths); } return $this; } /** * Load external resources * * @param DOMNodeList $files * @param array $paths * @return void */ private function loadExt(DOMNodeList $files, array &$paths = []): void { /** @var DOMElement $file */ foreach ($files as $file) { $baseName = basename($file->getAttribute("schemaLocation")); if (empty($paths[$baseName])) { $paths[$baseName] = true; $parent = $file->parentNode; $path = dirname($file->baseURI) . DIRECTORY_SEPARATOR . $file->getAttribute("schemaLocation"); if (file_exists($path)) { $xsd = new \MyDOMDocument(); $result = $xsd->load($path, LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_NOENT | LIBXML_XINCLUDE); if ($result) { $_PATHS[$file->getAttribute("schemaLocation")] = true; $xsd->loadImports($paths)->loadIncludes($paths); foreach ($xsd->documentElement->childNodes as $node) { $node = $this->importNode($node, true); $parent->insertBefore($node, $file); } } } $parent->removeChild($file); } } } }