如何将包含单引号和双引号的字符串作为参数传递给PHP中的XSLT?

如何将包含单引号和双引号的字符串作为参数传递给PHP中的XSLT?

问题描述:

我有一个简单的基于PHP的XSLT trasform代码看起来像这样:如何将包含单引号和双引号的字符串作为参数传递给PHP中的XSLT?

$xsl = new XSLTProcessor(); 
$xsl->registerPHPFunctions(); 
$xsl->setParameter("","searchterms", $searchterms); 
$xsl->importStylesheet($xslDoc); 
echo $xsl->transformToXML($doc); 

的代码将变量$ searchterms,其中包含一个字符串,作为参数传递给它轮流使用它的XSLT样式表为文本:

<title>search feed for <xsl:value-of select="$searchterms"/></title> 

,直到你试图传递一个字符串与它混合这工作得很好,说:

$searchterms = '"some"'." text's quotes are mixed." 

在这一点上XSLT处理器的尖叫声:

无法创建XPath表达式(字符串 同时包含引号和双引号)

什么是安全通过任意的字符串输入到XSLT正确的方法是什么?请注意,这些字符串将在结果XML中用作文本值,而不是XPATH参数。

感谢, 波阿斯

+0

addslashes可能会工作的u ..在添加它之前.. – 2010-04-29 12:35:45

如果你的最终输出是HTML,你可以尝试htmlencoding它。只要实体在样式表设置应该确定

你可以使用&apos;逃脱单引号:

$searchterms = '"some" text&apos;s quotes are mixed.' 

这已被记录为一个错误:

https://bugs.php.net/bug.php?id=64137

这评论:

这个缺点来自XPa的事实th 1.0没有提供转义字符的机制,所以PHP没有直接的方式来表达一个包含两种引号的字符串。不过,XPath 1.0提供了一个连接字符串的函数。使用concat(),由两个字符“''组成的字符串可以表示为concat('”',“'”)。 concat()需要2个或更多参数。

包括以下解决方法:所以只要你交替引用风格

,你可以表达包含任意数量的两种类型的引号的字符串。

另一种方案是用单引号替换所有直引号:

$t = str_replace("\"", "''", $t); 
$xsltEngine->setParameter("some-text", $t); 

这工作对我来说,使用替换HTML特殊字符单引号str_replace

$t = str_replace("'", "&#39;", $t); 
$xsltEngine->setParameter("some-text", $t); 

正如其中一个答案所示,这是一个错误。因此,您无法传递两个引号。

但是,您可以用另一个字符替换双引号,然后使用translate恢复原始。

要选择的主要内容是不会出现在您的文字上的字符。例如\x7F

$xsl = new XSLTProcessor(); 
$xsl->registerPHPFunctions(); 
$xsl->setParameter("","searchterms", strtr($searchterms, '"', "\x7F")); 
$xsl->importStylesheet($xslDoc); 
echo $xsl->transformToXML($doc); 

<title>search feed for <xsl:value-of select="translate($searchterms, '&#x7F;', '&quot;')"/></title> 

此外,您不能使用HTML实体,因为他们正在逃跑。

或者使用disable-output-escaping="yes"

<title>search feed for <xsl:value-of select="$searchterms" disable-output-escaping="yes"/></title> 

$xsl->setParameter("","searchterms", htmlspecialchars($searchterms)); 

您可以使用内置的表达式第一种方法。例如:

<title attr="foo {translate($searchterms, '&#x7F;', '&quot;')} bar">bazz</title>