I have a simple PHP-based XSLT trasform code that looks like that:
$xsl = new XSLTProcessor();
$xsl->registerPHPFunctions();
$xsl->setParameter("","searchterms", $searchterms);
$xsl->importStylesheet($xslDoc);
echo $xsl->transformToXML($doc);
The code passes the variable $searchterms, which contains a string, as a parameter to the XSLT style sheet which in turns uses it as a text:
<title>search feed for <xsl:value-of select="$searchterms"/></title>
This works fine until you try to pass a string with mixes in it, say:
$searchterms = '"some"'." text's quotes are mixed."
In that point the XSLT processor screams:
Cannot create XPath expression (string contains both quote and double-quotes)
What is the correct way to safely pass arbitrary strings as input to XSL开发者_运维技巧T? Note that these strings will be used as a text value in the resulting XML and not as an XPATH paramater.
Thanks, Boaz
This has been logged as a bug:
https://bugs.php.net/bug.php?id=64137
This comment:
This shortcoming comes from the fact that XPath 1.0 does not provide a mechanism to escape characters, so PHP does not have a straightforward way to express a string that contains both types of quotes. XPath 1.0 does, however, provide a function to concatenate strings. Using concat(), a string composed of the two characters "' can be expressed as concat('"',"'"). concat() takes 2 or more arguments.
Includes the following work-around:
So as long as you alternate the quoting style, you can express a string containing any number of quotes of both types.
Another solution is to replace all straight-quotes with single-quotes:
$t = str_replace( "\"", "''", $t );
$xsltEngine->setParameter( "some-text", $t );
if your final output is HTML you could try htmlencoding it. As long as entities are set in stylesheet should be OK
You could use '
to escape the single quotes:
$searchterms = '"some" text's quotes are mixed.'
This works for me to replace the single quotation marks with html special characters using str_replace
$t = str_replace("'", "'", $t);
$xsltEngine->setParameter( "some-text", $t );
As indicated in one of the answers, this is a bug. Therefore, you can not pass both quotes.
But you can replace the double quote with another character, and then use translate
to restore the original.
The main thing to choose is a character that will not appear on your text. For example \x7F
.
$xsl = new XSLTProcessor();
$xsl->registerPHPFunctions();
$xsl->setParameter("","searchterms", strtr($searchterms, '"', "\x7F"));
$xsl->importStylesheet($xslDoc);
echo $xsl->transformToXML($doc);
and
<title>search feed for <xsl:value-of select="translate($searchterms, '', '"')"/></title>
Also, you can not use html entities, since they are being escaped.
Or use disable-output-escaping="yes"
:
<title>search feed for <xsl:value-of select="$searchterms" disable-output-escaping="yes"/></title>
with
$xsl->setParameter("","searchterms", htmlspecialchars($searchterms));
The first method you can use for built-in expressions. For example:
<title attr="foo {translate($searchterms, '', '"')} bar">bazz</title>
精彩评论