В приведенной ниже функции, когда строка в ключевом слове $ содержит двойные кавычки, она создает «Предупреждение: DOMXPath :: evaluation (): Неверное выражение» :
$keyword = 'This is "causing" an error'; $xPath->evaluate('boolean(//img[contains(@alt, "'.$keyword.'")])');
Что мне следует сделать для $keyword
prep $keyword
для выражения выражения xpath?
Полный код функции:
$keyword = trim(strtolower(rseo_getKeyword($post))); function sx_function($heading, $post){ $content = $post->post_content; if($content=="" || !class_exists('DOMDocument')) return false; $keyword = trim(strtolower(rseo_getKeyword($post))); @$dom = new DOMDocument; @$dom->loadHTML(strtolower($post->post_content)); $xPath = new DOMXPath(@$dom); switch ($heading) { case "img-alt": return $xPath->evaluate('boolean(//img[contains(@alt, "'.$keyword.'")])'); default: return $xPath->evaluate('boolean(/html/body//'.$heading.'[contains(.,"'.$keyword.'")])'); } }
PHP имеет Xpath 1.0, если у вас есть строка с двойными и одинарными кавычками, обходной путь использует функцию Xpath concat concat()
. Вспомогательная функция может решить, когда использовать что. Пример / Использование:
xpath_string('I lowe "double" quotes.'); // xpath: 'I lowe "double" quotes.' xpath_string('It\'s my life.'); // xpath: "It's my life." xpath_string('Say: "Hello\'sen".'); // xpath: concat('Say: "Hello', "'", "'sen".')
Вспомогательная функция:
/** * xpath string handling xpath 1.0 "quoting" * * @param string $input * @return string */ function xpath_string($input) { if (false === strpos($input, "'")) { return "'$input'"; } if (false === strpos($input, '"')) { return "\"$input\""; } return "concat('" . strtr($input, array("'" => '\', "\'", \'')) . "')"; }
Чтобы избежать строковых разделителей в строковых литералах XPath 2.0, вам нужно заменить каждый отдельный разделитель на два, поэтому "
нужно заменить на ""
:
[74] StringLiteral ::= ('"' (EscapeQuot | [^"])* '"') | ("'" (EscapeApos | [^'])* "'") /* ws: explicit */ [75] EscapeQuot ::= '""' [76] EscapeApos ::= "''"
Я не уверен, есть ли у вас функция, но вы можете использовать эту функцию:
function xpath_quote($str, $quotation='"') { if ($quotation != '"' && $quotation != "'") return false; return str_replace($quotation, $quotation.$quotation, $str); }
И использование:
'boolean(/html/body//'.$heading.'[contains(.,"'.xpath_quote($keyword).'")])'