فهرست منبع

[CssSelector] fixed XPathExpr::xpathliteral()

Fabien Potencier 15 سال پیش
والد
کامیت
13759a7fac
2فایلهای تغییر یافته به همراه53 افزوده شده و 15 حذف شده
  1. 18 15
      src/Symfony/Components/CssSelector/XPathExpr.php
  2. 35 0
      tests/Symfony/Tests/Components/CssSelector/XPathExprTest.php

+ 18 - 15
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, ', '));
   }
 }

+ 35 - 0
tests/Symfony/Tests/Components/CssSelector/XPathExprTest.php

@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * 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"\')'),
+    );
+  }
+}