XPath на самом деле включает в себя метод безопасного выполнения этих действий, который допускает ссылки на переменные в форме $varname
в выражениях. Библиотека, на которой основан PHP * SimpleXML , предоставляет интерфейс для предоставления переменных , однако это не предоставляется функцией xpath в вашем примере.
Как демонстрация того, насколько просто это может быть:
>>> from lxml import etree
>>> n = etree.fromstring('<n a=\'He said "I'm here"\'/>')
>>> n.xpath("@a=$maybeunsafe", maybeunsafe='He said "I\'m here"')
True
Используется lxml , оболочка Python для той же базовой библиотеки, что и SimpleXML, с аналогичной функцией xpath . Булевы числа, числа и наборы узлов также могут передаваться напрямую.
Если переключение на более способный интерфейс XPath не является возможным, обходной путь, когда заданная внешняя строка будет чем-то (не стесняйтесь адаптироваться к PHP), в виде:
def safe_xpath_string(strvar):
if "'" in strvar:
return "',\"'\",'".join(strvar.split("'")).join(("concat('","')"))
return strvar.join("''")
Возвращаемое значение может быть непосредственно вставлено в строку выражения. Поскольку это на самом деле не очень читабельно, вот как оно ведет себя:
>>> print safe_xpath_string("basic")
'basic'
>>> print safe_xpath_string('He said "I\'m here"')
concat('He said "I',"'",'m here"')
Обратите внимание, вы не можете использовать экранирование в форме '
вне XML-документа, а также не применимы общие процедуры сериализации XML. Однако функцию concat XPath можно использовать для создания строки с кавычками обоих типов в любом контексте.
PHP-вариант:
function safe_xpath_string($value)
{
$quote = "'";
if (FALSE === strpos($value, $quote))
return $quote.$value.$quote;
else
return sprintf("concat('%s')", implode("', \"'\", '", explode($quote, $value)));
}