query($expression); $concepts = []; /** @var DOMElement $node */ foreach ($nodes as $node) { if(1) { $me_and_parents = array_merge([$node], self::getElementAncestors($node)); $path_segments = []; foreach ($me_and_parents as $me_or_parent) { if (!Navigator::isConcept($me_or_parent)) { // Silently skips invalid targeted nodes break; } $path_segments[] = self::conceptPathSegment($me_or_parent); } // Concept paths are have databox identifier at root level $concepts[] = new Concept(sprintf( '/%d/%s', $databox->get_sbas_id(), implode('/', array_reverse($path_segments)) )); } else { $path = ''; // go up thru parents while ($node) { $v = null; for ($n = $node->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeType === XML_ELEMENT_NODE && $n->nodeName === 'sy') { if ($v === null) { $v = $n->getAttribute('v'); continue; } if ($n->getAttribute('lng') === 'en') { $v = $n->getAttribute('v'); break; } } } if ($v !== null) { $path = '/' . $v . $path; } $node = $node->parentNode; } $path = '/' . $databox->get_sbas_id() . $path; $concepts[] = new Concept($path); } } return $concepts; } private static function getElementAncestors(DOMElement $element) { $parents = []; while (null !== $element = $element->parentNode) { $parents[] = $element; } return $parents; } /** * @param databox $databox * @return DOMDocument */ public static function thesaurusFromDatabox(databox $databox) { return self::document($databox->get_dom_thesaurus()); } public static function candidatesFromDatabox(databox $databox) { $document = $databox->get_dom_cterms(); if (!$document) { $document = new DOMDocument('1.0', 'UTF-8'); $document->xmlStandalone = true; $document->formatOutput = true; $element = $document->createElement('cterms'); $element->setAttribute('creation_date', date('YmdHis')); $element->setAttribute('next_id', 0); $element->setAttribute('version', '2.0.5'); $document->appendChild($element); } return $document; } /** * @param $document * @return DOMDocument */ private static function document($document) { if (!$document) { return new DOMDocument('1.0', 'UTF-8'); } return $document; } public static function conceptPathSegment(DOMElement $element) { // Path segment is named according to the first english term, and // default to the first term. $terms = self::filter($element->childNodes, array(Navigator::class, 'isTerm')); $term = self::find($terms, array('self', 'isPathLang')); if (!$term) { if (isset($terms[0])) { $term = $terms[0]; } else { throw new ThesaurusException(sprintf('No term linked to concept at path "%s".', $element->getNodePath())); } } return StringUtils::slugify($term->getAttribute(self::TERM_VALUE_ATTR)); } private static function isPathLang(DOMElement $element) { return $element->getAttribute(self::TERM_LANG_ATTR) === self::PATH_LANG; } // DOM Helpers private static function filter(DOMNodeList $list, callable $callback) { $filtered = []; foreach ($list as $node) { if (call_user_func($callback, $node)) { $filtered[] = $node; } } return $filtered; } private static function find(array $list, callable $callback) { foreach ($list as $node) { if (call_user_func($callback, $node)) { return $node; } } } }