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

时间:2010-04-29 11:50:29

标签: php xslt string escaping quotes

我有一个简单的基于PHP的XSLT trasform代码,如下所示:

$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参数。

谢谢, 波阿斯

5 个答案:

答案 0 :(得分:1)

这已被记录为错误:

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

此评论:

  

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

包括以下解决方法:

  

因此,只要您替换引用样式,就可以表达包含两种类型的引号的字符串。

另一个解决方案是用单引号替换所有直引号:

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

答案 1 :(得分:0)

如果您的最终输出是HTML,您可以尝试htmlencoding它。只要在样式表中设置实体就可以了

答案 2 :(得分:0)

您可以使用&apos;来转义单引号:

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

答案 3 :(得分:0)

这适用于我使用str_replace

用html特殊字符替换单引号
$t = str_replace("'", "&#39;", $t);  
$xsltEngine->setParameter( "some-text", $t );

答案 4 :(得分:0)

如其中一个答案所示,这是一个错误。因此,您不能同时传递这两个引号。

但您可以将双引号替换为另一个字符,然后使用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>