feeds_ex-8.x-1.0-alpha4/src/Feeds/Parser/QueryPathXmlParser.php
src/Feeds/Parser/QueryPathXmlParser.php
<?php namespace Drupal\feeds_ex\Feeds\Parser; use Drupal\Component\Render\HtmlEscapedText; use Drupal\feeds\FeedInterface; use Drupal\feeds\Result\FetcherResultInterface; use Drupal\feeds\StateInterface; use QueryPath\CSS\ParseException; use QueryPath\DOMQuery; use QueryPath\QueryPath; /** * Defines a XML parser using QueryPath. * * @FeedsParser( * id = "querypathxml", * title = @Translation("QueryPath XML"), * description = @Translation("Parse XML with QueryPath.") * ) */ class QueryPathXmlParser extends XmlParser { /** * Options passed to QueryPath. * * @var array */ protected $queryPathOptions = [ 'ignore_parser_warnings' => TRUE, 'use_parser' => 'xml', 'strip_low_ascii' => FALSE, 'replace_entities' => FALSE, 'omit_xml_declaration' => TRUE, 'encoding' => 'UTF-8', ]; /** * {@inheritdoc} */ protected function setUp(FeedInterface $feed, FetcherResultInterface $fetcher_result, StateInterface $state) { parent::setUp($feed, $fetcher_result, $state); $this->sources = $feed->getType()->getCustomSources(['querypathxml']); } /** * {@inheritdoc} */ protected function executeContext(FeedInterface $feed, FetcherResultInterface $fetcher_result, StateInterface $state) { $document = $this->prepareDocument($feed, $fetcher_result); $query_path = QueryPath::with($document, $this->configuration['context']['value'], $this->queryPathOptions); if (!$state->total) { $state->total = $query_path->size(); } $start = (int) $state->pointer; $state->pointer = $start + $this->configuration['line_limit']; $state->progress($state->total, $state->pointer); return $query_path->slice($start, $this->configuration['line_limit']); } /** * {@inheritdoc} */ protected function executeSourceExpression($machine_name, $expression, $row) { $result = QueryPath::with($row, $expression, $this->queryPathOptions); if ($result->size() == 0) { return; } $config = $this->sources[$machine_name] + [ 'attribute' => '', ]; $return = []; if (strlen($config['attribute'])) { foreach ($result as $node) { $return[] = $node->attr($config['attribute']); } } elseif (!empty($config['inner'])) { foreach ($result as $node) { $return[] = $node->innerXML(); } } elseif (!empty($config['raw'])) { foreach ($result as $node) { $return[] = $this->getRawValue($node); } } else { foreach ($result as $node) { $return[] = $node->text(); } } // Return a single value if there's only one value. return count($return) === 1 ? reset($return) : $return; } /** * Returns the raw value. * * @param \QueryPath\DOMQuery $node * The DOMQuery object to return a raw value for. * * @return string * A raw string value. */ protected function getRawValue(DOMQuery $node) { return $node->xml(); } /** * {@inheritdoc} */ protected function validateExpression(&$expression) { $this->loadLibrary(); $expression = trim($expression); if (!$expression) { return; } try { $parser = QueryPath::with(NULL, $expression); } catch (ParseException $e) { return new HtmlEscapedText($e->getMessage()); } } /** * {@inheritdoc} */ public function getSupportedCustomSourcePlugins(): array { return ['querypathxml']; } /** * {@inheritdoc} */ protected function loadLibrary() { if (!class_exists(QueryPath::class)) { throw new \RuntimeException('The QueryPath library is not installed.'); } } }