diff --git a/src/Symfony/Components/CssSelector/XPathExpr.php b/src/Symfony/Components/CssSelector/XPathExpr.php index d29e436f51..970cea60a4 100644 --- a/src/Symfony/Components/CssSelector/XPathExpr.php +++ b/src/Symfony/Components/CssSelector/XPathExpr.php @@ -173,28 +173,31 @@ class XPathExpr if (false === strpos($s, "'")) { - $s = sprintf("'%s'", $s); + return sprintf("'%s'", $s); } - elseif (false === strpos($s, '"')) + + if (false === strpos($s, '"')) { - $s = sprintf('"%s"', $s); + return sprintf('"%s"', $s); } - else + + $string = $s; + $parts = array(); + while (true) { - $tmp = array(); - foreach (preg_split("#('+)#", $s) as $part) + if (false !== $pos = strpos($string, "'")) { - if (!$part) - { - continue; - } - - $tmp[] = sprintf(false !== strpos($part, "'") ? '"%s"' : "'%s'", $part); + $parts[] = sprintf("'%s'", substr($string, 0, $pos)); + $parts[] = "\"'\""; + $string = substr($string, $pos + 1); + } + else + { + $parts[] = "'$string'"; + break; } - - $s = sprintf("concat(%s)", implode($tmp, ',')); } - return $s; + return sprintf("concat(%s)", implode($parts, ', ')); } } diff --git a/tests/Symfony/Tests/Components/CssSelector/XPathExprTest.php b/tests/Symfony/Tests/Components/CssSelector/XPathExprTest.php new file mode 100644 index 0000000000..b8db2acaf2 --- /dev/null +++ b/tests/Symfony/Tests/Components/CssSelector/XPathExprTest.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Components\CssSelector; + +use Symfony\Components\CssSelector\XPathExpr; + +class XPathExprTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getXPathLiteralValues + */ + public function testXpathLiteral($value, $literal) + { + $this->assertEquals($literal, XPathExpr::xpathLiteral($value)); + } + + public function getXPathLiteralValues() + { + return array( + array('foo', "'foo'"), + array("foo's bar", '"foo\'s bar"'), + array("foo's \"middle\" bar", 'concat(\'foo\', "\'", \'s "middle" bar\')'), + array("foo's 'middle' \"bar\"", 'concat(\'foo\', "\'", \'s \', "\'", \'middle\', "\'", \' "bar"\')'), + ); + } +}