Чтобы не было проблем с кавычками, надо использовать функцию из XPath concat(), где одинарные кавычки писать в двойных, а двойные в одинарных. Дебилизм, конечно, но я приципиально не хочу хранить языковые строки в базе (они у меня в xml).
А вот функция для PHP, которая искомую строку превращает в соответствующее выражение с concat, например, из строки I'm using " она сделает такое: concat("I","'","m using ",'"').
// Solves problem with ' and " in xpath expressions.
// As it seems, there is only one way to solve this:
// use concat() function from XPath, enclose the single quotes in double quotes,
// and the double quotes in single quotes.
//
// Example (from http://kushalm.com/the-perils-of-xpath-expressions-specifically-escaping-quotes):
// "books/book[@publisher = " + "concat('Single', "'", 'quote. Double', '"', 'quote.')]";
// looks for a publisher called Single'quote. Double"quote
function escape_xpath_subexpression($s)
{
// our quotes:
$specials = array('"', "'");
// how they are appear in concat() function:
$specials_replaced = array('\'"\'', '"\'"');
// if no special characters, it's the simplest case
$is_found = false;
foreach ($specials as $sp)
if (mb_strpos($s, $sp, 0, 'utf-8') !== false)
{
$is_found = true;
break;
}
if (!$is_found)
return '"'.$s.'"';
// otherwise processing string in cool way
$substs = array();
foreach ($specials as $i => $sp)
$substs[] = "##$i##";
$s = str_replace($specials, $substs, $s);
$substrings = preg_split('/(##\d+##)/', $s, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach ($substrings as $i => $substr)
{
$substr = str_replace($substs, $specials, $substr);
if (($idx = array_search($substr, $specials)) === false)
$substrings[$i] = '"'.$substr.'"';
else
$substrings[$i] = $specials_replaced[$idx];
}
return 'concat('.implode(',', $substrings).')';
}