2011-01-27 60 views
3

在下面的功能,當字符串中的$關鍵字包含雙引號,它創建一個「警告:DOMXPath ::評估():無效的表達式」如何在XPath評估之前處理字符串中的雙引號?

$keyword = 'This is "causing" an error'; 
$xPath->evaluate('boolean(//img[contains(@alt, "'.$keyword.'")])'); 

我應該怎麼做來準備$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.'")])'); 
     } 
} 

回答

3

逃避XPath 2.0 string literals字符串分隔符,你需要用兩個替換每個單獨的分隔符,所以"需要由""更換:

[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).'")])' 
+4

`DOMXPath`是Xpath的1.0,則鏈接中的XPath 2.0規範。 – hakre 2012-10-10 01:21:00

6

PHP有XPath 1.0中,如果你有雙和單引號的字符串,一個解決辦法是使用XPath 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("'" => '\', "\'", \'')) . "')"; 
} 
+0

這是一個rad解決方案。 – 2015-09-25 01:18:22