From cd83bfc9d134415e0f217fca988c31678c4bf04d Mon Sep 17 00:00:00 2001 From: Miha Vrhovnik Date: Wed, 27 Nov 2013 10:31:15 +0100 Subject: [PATCH 1/3] When serializing into the xml the string property can be marked as not to be enclosed inside CDATA Also fixed a bug where property metadata was not pushed onto the stack --- src/JMS/Serializer/Annotation/XmlElement.php | 31 +++++++++++++++++++ src/JMS/Serializer/Annotation/XmlValue.php | 4 +++ .../Metadata/Driver/AnnotationDriver.php | 5 +++ .../Serializer/Metadata/Driver/XmlDriver.php | 7 +++++ .../Serializer/Metadata/Driver/YamlDriver.php | 7 +++++ .../Serializer/Metadata/PropertyMetadata.php | 3 ++ .../Metadata/StaticPropertyMetadata.php | 2 ++ .../Metadata/VirtualPropertyMetadata.php | 2 ++ .../Serializer/XmlSerializationVisitor.php | 20 ++++++++++-- .../Serializer/Tests/Fixtures/BlogPost.php | 8 +++++ .../JMS/Serializer/Tests/Fixtures/Person.php | 3 +- .../Tests/Metadata/Driver/BaseDriverTest.php | 14 +++++++++ .../Tests/Metadata/Driver/php/BlogPost.php | 6 ++++ .../Tests/Metadata/Driver/php/Person.php | 20 ++++++++++++ .../Tests/Metadata/Driver/xml/BlogPost.xml | 3 ++ .../Tests/Metadata/Driver/xml/Person.xml | 9 ++++++ .../Tests/Metadata/Driver/yml/BlogPost.yml | 5 +++ .../Tests/Metadata/Driver/yml/Person.yml | 11 +++++++ .../Serializer/JsonSerializationTest.php | 4 +-- .../Tests/Serializer/xml/blog_post.xml | 1 + .../Serializer/xml/person_collection.xml | 2 +- .../Tests/Serializer/xml/person_location.xml | 2 +- .../Tests/Serializer/yml/blog_post.yml | 1 + .../Serializer/yml/blog_post_unauthored.yml | 1 + 24 files changed, 164 insertions(+), 7 deletions(-) create mode 100644 src/JMS/Serializer/Annotation/XmlElement.php create mode 100644 tests/JMS/Serializer/Tests/Metadata/Driver/php/Person.php create mode 100644 tests/JMS/Serializer/Tests/Metadata/Driver/xml/Person.xml create mode 100644 tests/JMS/Serializer/Tests/Metadata/Driver/yml/Person.yml diff --git a/src/JMS/Serializer/Annotation/XmlElement.php b/src/JMS/Serializer/Annotation/XmlElement.php new file mode 100644 index 000000000..d4b893013 --- /dev/null +++ b/src/JMS/Serializer/Annotation/XmlElement.php @@ -0,0 +1,31 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\Serializer\Annotation; + +/** + * @Annotation + * @Target({"PROPERTY","METHOD"}) + */ +final class XmlElement +{ + /** + * @var boolean + */ + public $cdata = true; +} diff --git a/src/JMS/Serializer/Annotation/XmlValue.php b/src/JMS/Serializer/Annotation/XmlValue.php index c221043fd..fa83fca1f 100644 --- a/src/JMS/Serializer/Annotation/XmlValue.php +++ b/src/JMS/Serializer/Annotation/XmlValue.php @@ -24,4 +24,8 @@ */ final class XmlValue { + /** + * @var boolean + */ + public $cdata = true; } diff --git a/src/JMS/Serializer/Metadata/Driver/AnnotationDriver.php b/src/JMS/Serializer/Metadata/Driver/AnnotationDriver.php index 966dfddd8..1cf142a6e 100644 --- a/src/JMS/Serializer/Metadata/Driver/AnnotationDriver.php +++ b/src/JMS/Serializer/Metadata/Driver/AnnotationDriver.php @@ -30,10 +30,12 @@ use JMS\Serializer\Annotation\XmlList; use JMS\Serializer\Annotation\XmlValue; use JMS\Serializer\Annotation\XmlKeyValuePairs; +use JMS\Serializer\Annotation\XmlElement; use JMS\Serializer\Annotation\PostSerialize; use JMS\Serializer\Annotation\PostDeserialize; use JMS\Serializer\Annotation\PreSerialize; use JMS\Serializer\Annotation\VirtualProperty; +use JMS\Serializer\Metadata\XmlElementMetadata; use Metadata\MethodMetadata; use Doctrine\Common\Annotations\Reader; use JMS\Serializer\Annotation\Type; @@ -169,6 +171,9 @@ public function loadMetadataForClass(\ReflectionClass $class) $propertyMetadata->xmlAttribute = true; } elseif ($annot instanceof XmlValue) { $propertyMetadata->xmlValue = true; + $propertyMetadata->xmlElementCData = $annot->cdata; + } elseif ($annot instanceof XmlElement) { + $propertyMetadata->xmlElementCData = $annot->cdata; } elseif ($annot instanceof AccessType) { $accessType = $annot->type; } elseif ($annot instanceof ReadOnly) { diff --git a/src/JMS/Serializer/Metadata/Driver/XmlDriver.php b/src/JMS/Serializer/Metadata/Driver/XmlDriver.php index 0df869e58..a82f4dd71 100644 --- a/src/JMS/Serializer/Metadata/Driver/XmlDriver.php +++ b/src/JMS/Serializer/Metadata/Driver/XmlDriver.php @@ -171,6 +171,13 @@ protected function loadMetadataFromFile(\ReflectionClass $class, $path) } } + if (isset($pElem->{'xml-element'})) { + $colConfig = $pElem->{'xml-element'}; + if (isset($colConfig->attributes()->cdata)) { + $pMetadata->xmlElementCData = 'true' === (string) $colConfig->attributes()->cdata; + } + } + if (isset($pElem->attributes()->{'xml-attribute'})) { $pMetadata->xmlAttribute = 'true' === (string) $pElem->attributes()->{'xml-attribute'}; } diff --git a/src/JMS/Serializer/Metadata/Driver/YamlDriver.php b/src/JMS/Serializer/Metadata/Driver/YamlDriver.php index 8cc9c50fe..d1d2b24e9 100644 --- a/src/JMS/Serializer/Metadata/Driver/YamlDriver.php +++ b/src/JMS/Serializer/Metadata/Driver/YamlDriver.php @@ -162,6 +162,13 @@ protected function loadMetadataFromFile(\ReflectionClass $class, $file) } } + if (isset($pConfig['xml_element'])) { + $colConfig = $pConfig['xml_element']; + if (isset($colConfig['cdata'])) { + $pMetadata->xmlElementCData = (Boolean) $colConfig['cdata']; + } + } + if (isset($pConfig['xml_attribute'])) { $pMetadata->xmlAttribute = (Boolean) $pConfig['xml_attribute']; } diff --git a/src/JMS/Serializer/Metadata/PropertyMetadata.php b/src/JMS/Serializer/Metadata/PropertyMetadata.php index a19416759..73e38b14c 100644 --- a/src/JMS/Serializer/Metadata/PropertyMetadata.php +++ b/src/JMS/Serializer/Metadata/PropertyMetadata.php @@ -39,6 +39,7 @@ class PropertyMetadata extends BasePropertyMetadata public $xmlAttribute = false; public $xmlValue = false; public $xmlKeyValuePairs = false; + public $xmlElementCData = true; public $getter; public $setter; public $inline = false; @@ -109,6 +110,7 @@ public function serialize() $this->xmlAttribute, $this->xmlValue, $this->xmlKeyValuePairs, + $this->xmlElementCData, $this->getter, $this->setter, $this->inline, @@ -134,6 +136,7 @@ public function unserialize($str) $this->xmlAttribute, $this->xmlValue, $this->xmlKeyValuePairs, + $this->xmlElementCData, $this->getter, $this->setter, $this->inline, diff --git a/src/JMS/Serializer/Metadata/StaticPropertyMetadata.php b/src/JMS/Serializer/Metadata/StaticPropertyMetadata.php index 762151dcc..aad6eaa5b 100644 --- a/src/JMS/Serializer/Metadata/StaticPropertyMetadata.php +++ b/src/JMS/Serializer/Metadata/StaticPropertyMetadata.php @@ -59,6 +59,7 @@ public function serialize() $this->xmlAttribute, $this->xmlValue, $this->xmlKeyValuePairs, + $this->xmlElementCData, $this->getter, $this->setter, $this->inline, @@ -84,6 +85,7 @@ public function unserialize($str) $this->xmlAttribute, $this->xmlValue, $this->xmlKeyValuePairs, + $this->xmlElementCData, $this->getter, $this->setter, $this->inline, diff --git a/src/JMS/Serializer/Metadata/VirtualPropertyMetadata.php b/src/JMS/Serializer/Metadata/VirtualPropertyMetadata.php index 552aac94b..d430fcfbd 100644 --- a/src/JMS/Serializer/Metadata/VirtualPropertyMetadata.php +++ b/src/JMS/Serializer/Metadata/VirtualPropertyMetadata.php @@ -58,6 +58,7 @@ public function serialize() $this->xmlAttribute, $this->xmlValue, $this->xmlKeyValuePairs, + $this->xmlElementCData, $this->getter, $this->setter, $this->inline, @@ -82,6 +83,7 @@ public function unserialize($str) $this->xmlAttribute, $this->xmlValue, $this->xmlKeyValuePairs, + $this->xmlElementCData, $this->getter, $this->setter, $this->inline, diff --git a/src/JMS/Serializer/XmlSerializationVisitor.php b/src/JMS/Serializer/XmlSerializationVisitor.php index 5aa464c52..1b52c5d6d 100644 --- a/src/JMS/Serializer/XmlSerializationVisitor.php +++ b/src/JMS/Serializer/XmlSerializationVisitor.php @@ -100,14 +100,21 @@ public function visitNull($data, array $type, Context $context) public function visitString($data, array $type, Context $context) { + + if (null !== $this->currentMetadata) { + $doCData = $this->currentMetadata->xmlElementCData; + } else { + $doCData = true; + } + if (null === $this->document) { $this->document = $this->createDocument(null, null, true); - $this->currentNode->appendChild($this->document->createCDATASection($data)); + $this->currentNode->appendChild($doCData ? $this->document->createCDATASection($data) : $this->document->createTextNode((string) $data)); return; } - return $this->document->createCDATASection($data); + return $doCData ? $this->document->createCDATASection($data) : $this->document->createTextNode((string) $data); } public function visitBoolean($data, array $type, Context $context) @@ -179,7 +186,10 @@ public function visitProperty(PropertyMetadata $metadata, $object, Context $cont } if ($metadata->xmlAttribute) { + $this->setCurrentMetadata($metadata); $node = $this->navigator->accept($v, $metadata->type, $context); + $this->revertCurrentMetadata(); + if (!$node instanceof \DOMCharacterData) { throw new RuntimeException(sprintf('Unsupported value for XML attribute. Expected character data, but got %s.', json_encode($v))); } @@ -197,7 +207,10 @@ public function visitProperty(PropertyMetadata $metadata, $object, Context $cont if ($metadata->xmlValue) { $this->hasValue = true; + $this->setCurrentMetadata($metadata); $node = $this->navigator->accept($v, $metadata->type, $context); + $this->revertCurrentMetadata(); + if (!$node instanceof \DOMCharacterData) { throw new RuntimeException(sprintf('Unsupported value for property %s::$%s. Expected character data, but got %s.', $metadata->reflection->class, $metadata->reflection->name, is_object($node) ? get_class($node) : gettype($node))); } @@ -213,7 +226,10 @@ public function visitProperty(PropertyMetadata $metadata, $object, Context $cont } foreach ($v as $key => $value) { + $this->setCurrentMetadata($metadata); $node = $this->navigator->accept($value, null, $context); + $this->revertCurrentMetadata(); + if (!$node instanceof \DOMCharacterData) { throw new RuntimeException(sprintf('Unsupported value for a XML attribute map value. Expected character data, but got %s.', json_encode($v))); } diff --git a/tests/JMS/Serializer/Tests/Fixtures/BlogPost.php b/tests/JMS/Serializer/Tests/Fixtures/BlogPost.php index 8efb59242..4fbc03110 100644 --- a/tests/JMS/Serializer/Tests/Fixtures/BlogPost.php +++ b/tests/JMS/Serializer/Tests/Fixtures/BlogPost.php @@ -24,6 +24,7 @@ use JMS\Serializer\Annotation\XmlRoot; use JMS\Serializer\Annotation\XmlAttribute; use JMS\Serializer\Annotation\XmlList; +use JMS\Serializer\Annotation\XmlElement; use JMS\Serializer\Annotation\Groups; use Doctrine\Common\Collections\ArrayCollection; use PhpCollection\Map; @@ -32,6 +33,13 @@ /** @XmlRoot("blog-post") */ class BlogPost { + /** + * @Type("string") + * @XmlElement(cdata=false) + * @Groups({"comments","post"}) + */ + private $id = 'what_a_nice_id'; + /** * @Type("string") * @Groups({"comments","post"}) diff --git a/tests/JMS/Serializer/Tests/Fixtures/Person.php b/tests/JMS/Serializer/Tests/Fixtures/Person.php index 9ff419c90..522cd8a04 100644 --- a/tests/JMS/Serializer/Tests/Fixtures/Person.php +++ b/tests/JMS/Serializer/Tests/Fixtures/Person.php @@ -21,6 +21,7 @@ use JMS\Serializer\Annotation\XmlAttribute; use JMS\Serializer\Annotation\XmlValue; use JMS\Serializer\Annotation\XmlRoot; +use JMS\Serializer\Annotation\XmlElement; use JMS\Serializer\Annotation\Type; /** @@ -30,7 +31,7 @@ class Person { /** * @Type("string") - * @XmlValue + * @XmlValue(cdata=false) */ public $name; diff --git a/tests/JMS/Serializer/Tests/Metadata/Driver/BaseDriverTest.php b/tests/JMS/Serializer/Tests/Metadata/Driver/BaseDriverTest.php index f198735a9..18a0e3d0c 100644 --- a/tests/JMS/Serializer/Tests/Metadata/Driver/BaseDriverTest.php +++ b/tests/JMS/Serializer/Tests/Metadata/Driver/BaseDriverTest.php @@ -32,6 +32,12 @@ public function testLoadBlogPostMetadata() $this->assertNotNull($m); $this->assertEquals('blog-post', $m->xmlRootName); + $p = new PropertyMetadata($m->name, 'id'); + $p->type = array('name' => 'string', 'params' => array()); + $p->groups = array("comments","post"); + $p->xmlElementCData = false; + $this->assertEquals($p, $m->propertyMetadata['id']); + $p = new PropertyMetadata($m->name, 'title'); $p->type = array('name' => 'string', 'params' => array()); $p->groups = array("comments","post"); @@ -152,6 +158,14 @@ public function testMaxDepth() $this->assertEquals(2, $m->propertyMetadata['children']->maxDepth); } + public function testPersonCData() + { + $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\Person')); + + $this->assertNotNull($m); + $this->assertFalse($m->propertyMetadata['name']->xmlElementCData); + } + /** * @return DriverInterface */ diff --git a/tests/JMS/Serializer/Tests/Metadata/Driver/php/BlogPost.php b/tests/JMS/Serializer/Tests/Metadata/Driver/php/BlogPost.php index e3973ce4c..8a978720e 100644 --- a/tests/JMS/Serializer/Tests/Metadata/Driver/php/BlogPost.php +++ b/tests/JMS/Serializer/Tests/Metadata/Driver/php/BlogPost.php @@ -6,6 +6,12 @@ $metadata = new ClassMetadata('JMS\Serializer\Tests\Fixtures\BlogPost'); $metadata->xmlRootName = 'blog-post'; +$pMetadata = new PropertyMetadata('JMS\Serializer\Tests\Fixtures\BlogPost', 'id'); +$pMetadata->setType('string'); +$pMetadata->groups = array('comments','post'); +$pMetadata->xmlElementCData = false; +$metadata->addPropertyMetadata($pMetadata); + $pMetadata = new PropertyMetadata('JMS\Serializer\Tests\Fixtures\BlogPost', 'title'); $pMetadata->setType('string'); $pMetadata->groups = array('comments','post'); diff --git a/tests/JMS/Serializer/Tests/Metadata/Driver/php/Person.php b/tests/JMS/Serializer/Tests/Metadata/Driver/php/Person.php new file mode 100644 index 000000000..1de706f28 --- /dev/null +++ b/tests/JMS/Serializer/Tests/Metadata/Driver/php/Person.php @@ -0,0 +1,20 @@ +xmlRootName = 'child'; + +$pMetadata = new PropertyMetadata('JMS\Serializer\Tests\Fixtures\Person', 'name'); +$pMetadata->setType('string'); +$pMetadata->xmlValue = true; +$pMetadata->xmlElementCData = false; +$metadata->addPropertyMetadata($pMetadata); + +$pMetadata = new PropertyMetadata('JMS\Serializer\Tests\Fixtures\Person', 'age'); +$pMetadata->setType('integer'); +$pMetadata->xmlAttribute = true; +$metadata->addPropertyMetadata($pMetadata); + +return $metadata; diff --git a/tests/JMS/Serializer/Tests/Metadata/Driver/xml/BlogPost.xml b/tests/JMS/Serializer/Tests/Metadata/Driver/xml/BlogPost.xml index c605b65cb..147d5f475 100644 --- a/tests/JMS/Serializer/Tests/Metadata/Driver/xml/BlogPost.xml +++ b/tests/JMS/Serializer/Tests/Metadata/Driver/xml/BlogPost.xml @@ -1,6 +1,9 @@ + + + diff --git a/tests/JMS/Serializer/Tests/Metadata/Driver/xml/Person.xml b/tests/JMS/Serializer/Tests/Metadata/Driver/xml/Person.xml new file mode 100644 index 000000000..a723e7baf --- /dev/null +++ b/tests/JMS/Serializer/Tests/Metadata/Driver/xml/Person.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/tests/JMS/Serializer/Tests/Metadata/Driver/yml/BlogPost.yml b/tests/JMS/Serializer/Tests/Metadata/Driver/yml/BlogPost.yml index 2be24264d..3f359d49a 100644 --- a/tests/JMS/Serializer/Tests/Metadata/Driver/yml/BlogPost.yml +++ b/tests/JMS/Serializer/Tests/Metadata/Driver/yml/BlogPost.yml @@ -1,6 +1,11 @@ JMS\Serializer\Tests\Fixtures\BlogPost: xml_root_name: blog-post properties: + id: + type: string + groups: [comments, post] + xml_element: + cdata: false title: type: string groups: [comments, post] diff --git a/tests/JMS/Serializer/Tests/Metadata/Driver/yml/Person.yml b/tests/JMS/Serializer/Tests/Metadata/Driver/yml/Person.yml new file mode 100644 index 000000000..c98e8655d --- /dev/null +++ b/tests/JMS/Serializer/Tests/Metadata/Driver/yml/Person.yml @@ -0,0 +1,11 @@ +JMS\Serializer\Tests\Fixtures\Person: + xml_root_name: child + properties: + name: + type: string + xml_value: true + xml_element: + cdata: false + age: + type: integer + xml_attribute: true diff --git a/tests/JMS/Serializer/Tests/Serializer/JsonSerializationTest.php b/tests/JMS/Serializer/Tests/Serializer/JsonSerializationTest.php index 54c363453..95ad559a4 100644 --- a/tests/JMS/Serializer/Tests/Serializer/JsonSerializationTest.php +++ b/tests/JMS/Serializer/Tests/Serializer/JsonSerializationTest.php @@ -49,8 +49,8 @@ protected function getContent($key) $outputs['array_floats'] = '[1.34,3,6.42]'; $outputs['array_objects'] = '[{"foo":"foo","moo":"bar","camel_case":"boo"},{"foo":"baz","moo":"boo","camel_case":"boo"}]'; $outputs['array_mixed'] = '["foo",1,true,{"foo":"foo","moo":"bar","camel_case":"boo"},[1,3,true]]'; - $outputs['blog_post'] = '{"title":"This is a nice title.","created_at":"2011-07-30T00:00:00+0000","is_published":false,"comments":[{"author":{"full_name":"Foo Bar"},"text":"foo"}],"comments2":[{"author":{"full_name":"Foo Bar"},"text":"foo"}],"metadata":{"foo":"bar"},"author":{"full_name":"Foo Bar"}}'; - $outputs['blog_post_unauthored'] = '{"title":"This is a nice title.","created_at":"2011-07-30T00:00:00+0000","is_published":false,"comments":[],"comments2":[],"metadata":{"foo":"bar"},"author":null}'; + $outputs['blog_post'] = '{"id":"what_a_nice_id","title":"This is a nice title.","created_at":"2011-07-30T00:00:00+0000","is_published":false,"comments":[{"author":{"full_name":"Foo Bar"},"text":"foo"}],"comments2":[{"author":{"full_name":"Foo Bar"},"text":"foo"}],"metadata":{"foo":"bar"},"author":{"full_name":"Foo Bar"}}'; + $outputs['blog_post_unauthored'] = '{"id":"what_a_nice_id","title":"This is a nice title.","created_at":"2011-07-30T00:00:00+0000","is_published":false,"comments":[],"comments2":[],"metadata":{"foo":"bar"},"author":null}'; $outputs['price'] = '{"price":3}'; $outputs['currency_aware_price'] = '{"currency":"EUR","amount":2.34}'; $outputs['order'] = '{"cost":{"price":12.34}}'; diff --git a/tests/JMS/Serializer/Tests/Serializer/xml/blog_post.xml b/tests/JMS/Serializer/Tests/Serializer/xml/blog_post.xml index 430a46fc4..58eb655ca 100644 --- a/tests/JMS/Serializer/Tests/Serializer/xml/blog_post.xml +++ b/tests/JMS/Serializer/Tests/Serializer/xml/blog_post.xml @@ -1,5 +1,6 @@ + what_a_nice_id <![CDATA[This is a nice title.]]> diff --git a/tests/JMS/Serializer/Tests/Serializer/xml/person_collection.xml b/tests/JMS/Serializer/Tests/Serializer/xml/person_collection.xml index bc4a112c3..37654cc20 100644 --- a/tests/JMS/Serializer/Tests/Serializer/xml/person_collection.xml +++ b/tests/JMS/Serializer/Tests/Serializer/xml/person_collection.xml @@ -1,5 +1,5 @@ - + Matthias Noback diff --git a/tests/JMS/Serializer/Tests/Serializer/xml/person_location.xml b/tests/JMS/Serializer/Tests/Serializer/xml/person_location.xml index 00a2c2bc5..fa2aa87a6 100644 --- a/tests/JMS/Serializer/Tests/Serializer/xml/person_location.xml +++ b/tests/JMS/Serializer/Tests/Serializer/xml/person_location.xml @@ -1,5 +1,5 @@ - + Matthias Noback diff --git a/tests/JMS/Serializer/Tests/Serializer/yml/blog_post.yml b/tests/JMS/Serializer/Tests/Serializer/yml/blog_post.yml index a8f43f8cb..a24dae76a 100644 --- a/tests/JMS/Serializer/Tests/Serializer/yml/blog_post.yml +++ b/tests/JMS/Serializer/Tests/Serializer/yml/blog_post.yml @@ -1,3 +1,4 @@ +id: what_a_nice_id title: 'This is a nice title.' created_at: '2011-07-30T00:00:00+0000' is_published: false diff --git a/tests/JMS/Serializer/Tests/Serializer/yml/blog_post_unauthored.yml b/tests/JMS/Serializer/Tests/Serializer/yml/blog_post_unauthored.yml index df4745248..12836a09b 100644 --- a/tests/JMS/Serializer/Tests/Serializer/yml/blog_post_unauthored.yml +++ b/tests/JMS/Serializer/Tests/Serializer/yml/blog_post_unauthored.yml @@ -1,3 +1,4 @@ +id: what_a_nice_id title: 'This is a nice title.' created_at: '2011-07-30T00:00:00+0000' is_published: false From 787014d065779837b3ddebc84ff888a6459a7c03 Mon Sep 17 00:00:00 2001 From: Miha Vrhovnik Date: Wed, 27 Nov 2013 10:52:55 +0100 Subject: [PATCH 2/3] Updated documentation --- doc/reference/annotations.rst | 25 +++++++++++++++++++++++++ doc/reference/xml_reference.rst | 1 + doc/reference/yml_reference.rst | 2 ++ 3 files changed, 28 insertions(+) diff --git a/doc/reference/annotations.rst b/doc/reference/annotations.rst index d21af14f5..cd23663e0 100644 --- a/doc/reference/annotations.rst +++ b/doc/reference/annotations.rst @@ -398,6 +398,8 @@ Resulting XML: This allows you to mark properties which should be set as the value of the current element. Note that this has the limitation that any additional properties of that object must have the @XmlAttribute annotation. +XMlValue also has property cdata. Which has the same meaning as the one in +XMLElement. .. code-block :: php @@ -508,3 +510,26 @@ Resulting XML: .. code-block :: xml + +@XmlElement +~~~~~~~~ +This annotation can be defined on a property to add additional xml serialization/deserialization properties. + +.. code-block :: php + + my_id \ No newline at end of file diff --git a/doc/reference/xml_reference.rst b/doc/reference/xml_reference.rst index 88cdd8d5d..b920c12a0 100644 --- a/doc/reference/xml_reference.rst +++ b/doc/reference/xml_reference.rst @@ -32,6 +32,7 @@ XML Reference + diff --git a/doc/reference/yml_reference.rst b/doc/reference/yml_reference.rst index 2c1f909d9..2115e3a71 100644 --- a/doc/reference/yml_reference.rst +++ b/doc/reference/yml_reference.rst @@ -42,6 +42,8 @@ YAML Reference key_attribute_name: foo entry_name: bar xml_attribute_map: true + xml_element: + cdata: false max_depth: 2 handler_callbacks: From efffbe24a13e82599689d84423ef2b83c104d339 Mon Sep 17 00:00:00 2001 From: Miha Vrhovnik Date: Thu, 28 Nov 2013 11:49:48 +0100 Subject: [PATCH 3/3] Added visitSimpleString function into the XmlSerializationVisitor. This method always serializes data into a text node. DateTimeHandler supports that newly added feature. --- src/JMS/Serializer/Handler/DateHandler.php | 12 +++++++++++- .../Serializer/XmlSerializationVisitor.php | 12 ++++++++++++ .../Tests/Serializer/XmlSerializationTest.php | 19 +++++++++++++++++++ .../Serializer/xml/date_time_no_cdata.xml | 2 ++ 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 tests/JMS/Serializer/Tests/Serializer/xml/date_time_no_cdata.xml diff --git a/src/JMS/Serializer/Handler/DateHandler.php b/src/JMS/Serializer/Handler/DateHandler.php index dd8e44d15..22505816c 100644 --- a/src/JMS/Serializer/Handler/DateHandler.php +++ b/src/JMS/Serializer/Handler/DateHandler.php @@ -24,11 +24,13 @@ use JMS\Serializer\Exception\RuntimeException; use JMS\Serializer\VisitorInterface; use JMS\Serializer\GraphNavigator; +use JMS\Serializer\XmlSerializationVisitor; class DateHandler implements SubscribingHandlerInterface { private $defaultFormat; private $defaultTimezone; + private $xmlCData; public static function getSubscribingMethods() { @@ -55,14 +57,18 @@ public static function getSubscribingMethods() return $methods; } - public function __construct($defaultFormat = \DateTime::ISO8601, $defaultTimezone = 'UTC') + public function __construct($defaultFormat = \DateTime::ISO8601, $defaultTimezone = 'UTC', $xmlCData = true) { $this->defaultFormat = $defaultFormat; $this->defaultTimezone = new \DateTimeZone($defaultTimezone); + $this->xmlCData = $xmlCData; } public function serializeDateTime(VisitorInterface $visitor, \DateTime $date, array $type, Context $context) { + if ($visitor instanceof XmlSerializationVisitor && false === $this->xmlCData) { + return $visitor->visitSimpleString($date->format($this->getFormat($type)), $type, $context); + } return $visitor->visitString($date->format($this->getFormat($type)), $type, $context); } @@ -70,6 +76,10 @@ public function serializeDateInterval(VisitorInterface $visitor, \DateInterval $ { $iso8601DateIntervalString = $this->format($date); + if ($visitor instanceof XmlSerializationVisitor && false === $this->xmlCData) { + return $visitor->visitSimpleString($iso8601DateIntervalString, $type, $context); + } + return $visitor->visitString($iso8601DateIntervalString, $type, $context); } diff --git a/src/JMS/Serializer/XmlSerializationVisitor.php b/src/JMS/Serializer/XmlSerializationVisitor.php index 1b52c5d6d..5f6c0c2b4 100644 --- a/src/JMS/Serializer/XmlSerializationVisitor.php +++ b/src/JMS/Serializer/XmlSerializationVisitor.php @@ -117,6 +117,18 @@ public function visitString($data, array $type, Context $context) return $doCData ? $this->document->createCDATASection($data) : $this->document->createTextNode((string) $data); } + public function visitSimpleString($data, array $type, Context $context) + { + if (null === $this->document) { + $this->document = $this->createDocument(null, null, true); + $this->currentNode->appendChild($this->document->createTextNode((string) $data)); + + return; + } + + return $this->document->createTextNode((string) $data); + } + public function visitBoolean($data, array $type, Context $context) { if (null === $this->document) { diff --git a/tests/JMS/Serializer/Tests/Serializer/XmlSerializationTest.php b/tests/JMS/Serializer/Tests/Serializer/XmlSerializationTest.php index 0511a440b..86f815969 100644 --- a/tests/JMS/Serializer/Tests/Serializer/XmlSerializationTest.php +++ b/tests/JMS/Serializer/Tests/Serializer/XmlSerializationTest.php @@ -18,7 +18,11 @@ namespace JMS\Serializer\Tests\Serializer; +use JMS\Serializer\Construction\UnserializeObjectConstructor; +use JMS\Serializer\Handler\DateHandler; +use JMS\Serializer\Handler\HandlerRegistry; use JMS\Serializer\SerializationContext; +use JMS\Serializer\Serializer; use JMS\Serializer\Tests\Fixtures\InvalidUsageOfXmlValue; use JMS\Serializer\Exception\InvalidArgumentException; use JMS\Serializer\Tests\Fixtures\PersonCollection; @@ -141,6 +145,21 @@ public function testArrayKeyValues() $this->assertEquals($this->getContent('array_key_values'), $this->serializer->serialize(new ObjectWithXmlKeyValuePairs(), 'xml')); } + /** + * @dataProvider getDateTime + * @group datetime + */ + public function testDateTimeNoCData($key, $value, $type) + { + $handlerRegistry = new HandlerRegistry(); + $handlerRegistry->registerSubscribingHandler(new DateHandler(\DateTime::ISO8601, 'UTC', false)); + $objectConstructor = new UnserializeObjectConstructor(); + + $serializer = new Serializer($this->factory, $handlerRegistry, $objectConstructor, $this->serializationVisitors, $this->deserializationVisitors); + + $this->assertEquals($this->getContent($key . '_no_cdata'), $serializer->serialize($value, $this->getFormat())); + } + /** * @expectedException JMS\Serializer\Exception\RuntimeException * @expectedExceptionMessage Unsupported value type for XML attribute map. Expected array but got object diff --git a/tests/JMS/Serializer/Tests/Serializer/xml/date_time_no_cdata.xml b/tests/JMS/Serializer/Tests/Serializer/xml/date_time_no_cdata.xml new file mode 100644 index 000000000..b9c36c25a --- /dev/null +++ b/tests/JMS/Serializer/Tests/Serializer/xml/date_time_no_cdata.xml @@ -0,0 +1,2 @@ + +2011-08-30T00:00:00+0000