Explorar o código

Merge remote branch 'Brouznouf/master'

* Brouznouf/master:
  [Serializer] Revert DOMElement to SimpleXmlElement
  [Serializer] Using DOMElement instead of SimpleXmlElement in XmlEncoder to permit some behavior
Fabien Potencier %!s(int64=14) %!d(string=hai) anos
pai
achega
d95a743d9f

+ 12 - 3
src/Symfony/Component/Serializer/Encoder/XmlEncoder.php

@@ -165,12 +165,19 @@ class XmlEncoder extends AbstractEncoder
                         $value['@'.$attrkey] = (string) $attr;
                     }
                 }
+            } elseif ($subnode->attributes()) {
+                $value = array();
+                foreach ($subnode->attributes() as $attrkey => $attr) {
+                    $value['@'.$attrkey] = (string) $attr;
+                }
+                $value['#'] = (string) $subnode;
             } else {
                 $value = (string) $subnode;
             }
+            
             if ($key === 'item') {
-                if (isset($subnode['key'])) {
-                    $data[(string)$subnode['key']] = $value;
+                if (isset($value['@key'])) {
+                    $data[(string)$value['@key']] = $value['#'];
                 } elseif (isset($data['item'])) {
                     $tmp = $data['item'];
                     unset($data['item']);
@@ -178,7 +185,7 @@ class XmlEncoder extends AbstractEncoder
                     $data[] = $value;
                 }
             } elseif (key_exists($key, $data)) {
-                if (false === is_array($data[$key])) {
+                if ((false === is_array($data[$key]))  || (false === isset($data[$key][0]))) {
                     $data[$key] = array($data[$key]);
                 }
                 $data[$key][] = $value;
@@ -205,6 +212,8 @@ class XmlEncoder extends AbstractEncoder
                 //Ah this is the magic @ attribute types.
                 if (0 === strpos($key, "@") && is_scalar($data) && $this->isElementNameValid($attributeName = substr($key,1))) {
                     $parentNode->setAttribute($attributeName, $data);
+                } elseif ($key === '#') {
+                    $append = $this->selectNodeType($parentNode, $data);
                 } elseif (is_array($data) && false === is_numeric($key)) {
                     /**
                     * Is this array fully numeric keys?

+ 45 - 1
tests/Symfony/Tests/Component/Serializer/Encoder/XmlEncoderTest.php

@@ -111,6 +111,18 @@ class XmlEncoderTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
     }
+    
+    public function testEncodeScalarWithAttribute()
+    {
+        $array = array(
+            'person' => array('@gender' => 'M', '#' => 'Peter'),
+        );
+    
+        $expected = '<?xml version="1.0"?>'."\n".
+            '<response><person gender="M"><![CDATA[Peter]]></person></response>'."\n";
+    
+        $this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
+    }
 
     public function testDecodeScalar()
     {
@@ -135,6 +147,38 @@ class XmlEncoderTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals(get_object_vars($obj), $this->encoder->decode($source, 'xml'));
     }
+    
+    public function testDecodeScalarWithAttribute()
+    {
+        $source = '<?xml version="1.0"?>'."\n".
+            '<response><person gender="M">Peter</person></response>'."\n";
+      
+        $expected = array(
+            'person' => array('@gender' => 'M', '#' => 'Peter'),
+        );
+      
+        $this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
+    }
+    
+    public function testDecodeArray()
+    {
+        $source = '<?xml version="1.0"?>'."\n".
+            '<response>'.
+            '<people>'.
+            '<person><firstname>Benjamin</firstname><lastname>Alexandre</lastname></person>'.
+            '<person><firstname>Damien</firstname><lastname>Clay</lastname></person>'.
+            '</people>'.
+            '</response>'."\n";
+        
+        $expected = array(
+            'people' => array('person' => array(
+                array('firstname' => 'Benjamin', 'lastname' => 'Alexandre'),
+                array('firstname' => 'Damien', 'lastname' => 'Clay')
+            ))
+        );
+        
+        $this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
+    }
 
     protected function getXmlSource()
     {
@@ -153,7 +197,7 @@ class XmlEncoderTest extends \PHPUnit_Framework_TestCase
         $obj = new Dummy;
         $obj->foo = 'foo';
         $obj->bar = array('a', 'b');
-        $obj->baz = array('key' => 'val', 'key2' => 'val', 'A B' => 'bar', "Barry" => array('FooBar' => array("@id"=>1,"Baz"=>"Ed")));
+        $obj->baz = array('key' => 'val', 'key2' => 'val', 'A B' => 'bar', "Barry" => array('FooBar' => array("Baz"=>"Ed", "@id"=>1)));
         $obj->qux = "1";
         return $obj;
     }