How to handle double quotes in string before XPath evaluation?
In the function below, when string in $keyword contains double quotes, it does create a "Warning: DOMXPath::evaluate(): Invalid expression":
$keyword = 'This is "causing" an error';
$xPath->evaluate('boolean(//img[contains(@alt, "'.$keyword.'")])');
What should I do to prep $keyword
for the evaluate xpath expression?
The full function code:
$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->loadHT开发者_如何学CML(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 has Xpath 1.0, if you have a string with double and single quotes, a workaround is using the Xpath concat()
function. A helper function can decide when to use what. Example/Usage:
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".')
The helper function:
/**
* 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("'" => '\', "\'", \'')) . "')";
}
To escape the string delimiters in XPath 2.0 string literals you need to replace each single delimiter by two, so "
needs to be replaced by ""
:
[74] StringLiteral ::= ('"' (EscapeQuot | [^"])* '"') | ("'" (EscapeApos | [^'])* "'") /* ws: explicit */ [75] EscapeQuot ::= '""' [76] EscapeApos ::= "''"
I’m not sure if there already is a function to do that but you can use this function:
function xpath_quote($str, $quotation='"') {
if ($quotation != '"' && $quotation != "'") return false;
return str_replace($quotation, $quotation.$quotation, $str);
}
And the usage:
'boolean(/html/body//'.$heading.'[contains(.,"'.xpath_quote($keyword).'")])'
精彩评论