View source
<?php
namespace Drupal\feeds_xpathparser;
class XPathQueryParser {
protected $wordBoundaries = array(
'[',
']',
'=',
'(',
')',
'.',
'<',
'>',
'*',
'!',
'|',
'/',
',',
' ',
':',
);
protected $query;
protected $i;
protected $inQuotes = FALSE;
protected $quoteChar = '';
protected $word = '';
protected $output = '';
protected $prevBoundary = '';
protected $axis = '';
protected $skipNextWord = FALSE;
public function __construct($query) {
$this->query = preg_replace('/\\s+\\(\\s*/', '(', $query);
}
public function getQuery() {
$this
->start();
return $this->output;
}
protected function start() {
for ($i = 0; $i < drupal_strlen($this->query); $i++) {
$this->i = $i;
$c = drupal_substr($this->query, $i, 1);
if ($c === '"' || $c === "'") {
$this
->handleQuote($c);
continue;
}
if ($this->inQuotes) {
$this->word .= $c;
continue;
}
if (in_array($c, $this->wordBoundaries)) {
$this
->handleWordBoundary($c);
}
else {
$this->word .= $c;
}
}
$this
->handleWord();
}
protected function handleQuote($c) {
if ($this->inQuotes && $c === $this->quoteChar) {
$this->inQuotes = FALSE;
$this->word .= $c;
$this->output .= $this->word;
$this->word = '';
}
elseif (!$this->inQuotes) {
$this->inQuotes = TRUE;
$this
->handleWord();
$this->word = $c;
$this->quoteChar = $c;
}
else {
$this->word .= $c;
}
}
protected function handleWordBoundary($c) {
if (in_array($this->word, array(
'div',
'or',
'and',
'mod',
)) && $this->prevBoundary === ' ' && $c === ' ') {
$this->output .= $this->word;
}
else {
$this
->handleWord($c);
}
$this->output .= $c;
$this->word = '';
$this->prevBoundary = $c;
}
protected function handleWord($c = '') {
if ($this->word === '') {
return;
}
if ($c === ':' && drupal_substr($this->query, $this->i + 1, 1) === ':') {
$this->axis = $this->word;
}
if ($c === ':' && drupal_substr($this->query, $this->i - 1, 1) !== ':' && drupal_substr($this->query, $this->i + 1, 1) !== ':') {
$this->output .= $this->word;
$this->skipNextWord = TRUE;
return;
}
if ($this->skipNextWord) {
$this->skipNextWord = FALSE;
$this->output .= $this->word;
return;
}
if (is_numeric($this->word) || $this->axis === 'attribute' || strpos($this->word, '@') === 0 || $c === '(' || $c === ':') {
$this->output .= $this->word;
return;
}
$this->output .= '__default__:' . $this->word;
}
}