1717use Symfony \Component \Serializer \SerializerAwareTrait ;
1818
1919/**
20- * Encodes XML data.
21- *
2220 * @author Jordi Boggiano <j.boggiano@seld.be>
2321 * @author John Wards <jwards@whiteoctober.co.uk>
2422 * @author Fabian Vogler <fabian@equivalence.ch>
@@ -68,13 +66,6 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
6866self ::TYPE_CAST_ATTRIBUTES =>true ,
6967 ];
7068
71- /**
72- * @var \DOMDocument
73- */
74- private $ dom ;
75- private $ format ;
76- private $ context ;
77-
7869/**
7970 * @param array $defaultContext
8071 */
@@ -107,19 +98,17 @@ public function encode($data, $format, array $context = [])
10798
10899$ xmlRootNodeName =$ context [self ::ROOT_NODE_NAME ] ??$ this ->defaultContext [self ::ROOT_NODE_NAME ];
109100
110- $ this ->dom =$ this ->createDomDocument ($ context );
111- $ this ->format =$ format ;
112- $ this ->context =$ context ;
101+ $ dom =$ this ->createDomDocument ($ context );
113102
114103if (null !==$ data && !is_scalar ($ data )) {
115- $ root =$ this -> dom ->createElement ($ xmlRootNodeName );
116- $ this -> dom ->appendChild ($ root );
117- $ this ->buildXml ($ root ,$ data ,$ xmlRootNodeName );
104+ $ root =$ dom ->createElement ($ xmlRootNodeName );
105+ $ dom ->appendChild ($ root );
106+ $ this ->buildXml ($ root ,$ data ,$ format , $ context , $ xmlRootNodeName );
118107 }else {
119- $ this ->appendNode ($ this -> dom ,$ data ,$ xmlRootNodeName );
108+ $ this ->appendNode ($ dom ,$ data, $ format , $ context ,$ xmlRootNodeName );
120109 }
121110
122- return $ this -> dom ->saveXML ($ ignorePiNode ?$ this -> dom ->documentElement :null );
111+ return $ dom ->saveXML ($ ignorePiNode ?$ dom ->documentElement :null );
123112 }
124113
125114/**
@@ -242,7 +231,7 @@ public function getRootNodeName()
242231final protected function appendXMLString (\DOMNode $ node ,string $ val ):bool
243232 {
244233if ('' !==$ val ) {
245- $ frag =$ this -> dom ->createDocumentFragment ();
234+ $ frag =$ node -> ownerDocument ->createDocumentFragment ();
246235$ frag ->appendXML ($ val );
247236$ node ->appendChild ($ frag );
248237
@@ -254,15 +243,15 @@ final protected function appendXMLString(\DOMNode $node, string $val): bool
254243
255244final protected function appendText (\DOMNode $ node ,string $ val ):bool
256245 {
257- $ nodeText =$ this -> dom ->createTextNode ($ val );
246+ $ nodeText =$ node -> ownerDocument ->createTextNode ($ val );
258247$ node ->appendChild ($ nodeText );
259248
260249return true ;
261250 }
262251
263252final protected function appendCData (\DOMNode $ node ,string $ val ):bool
264253 {
265- $ nodeText =$ this -> dom ->createCDATASection ($ val );
254+ $ nodeText =$ node -> ownerDocument ->createCDATASection ($ val );
266255$ node ->appendChild ($ nodeText );
267256
268257return true ;
@@ -284,7 +273,7 @@ final protected function appendDocumentFragment(\DOMNode $node, $fragment): bool
284273
285274final protected function appendComment (\DOMNode $ node ,string $ data ):bool
286275 {
287- $ node ->appendChild ($ this -> dom ->createComment ($ data ));
276+ $ node ->appendChild ($ node -> ownerDocument ->createComment ($ data ));
288277
289278return true ;
290279 }
@@ -412,22 +401,22 @@ private function parseXmlValue(\DOMNode $node, array $context = [])
412401 *
413402 * @throws NotEncodableValueException
414403 */
415- private function buildXml (\DOMNode $ parentNode ,$ data ,string $ xmlRootNodeName =null ):bool
404+ private function buildXml (\DOMNode $ parentNode ,$ data ,string $ format , array $ context , string $ xmlRootNodeName =null ):bool
416405 {
417406$ append =true ;
418- $ removeEmptyTags =$ this -> context [self ::REMOVE_EMPTY_TAGS ] ??$ this ->defaultContext [self ::REMOVE_EMPTY_TAGS ] ??false ;
419- $ encoderIgnoredNodeTypes =$ this -> context [self ::ENCODER_IGNORED_NODE_TYPES ] ??$ this ->defaultContext [self ::ENCODER_IGNORED_NODE_TYPES ];
407+ $ removeEmptyTags =$ context [self ::REMOVE_EMPTY_TAGS ] ??$ this ->defaultContext [self ::REMOVE_EMPTY_TAGS ] ??false ;
408+ $ encoderIgnoredNodeTypes =$ context [self ::ENCODER_IGNORED_NODE_TYPES ] ??$ this ->defaultContext [self ::ENCODER_IGNORED_NODE_TYPES ];
420409
421- if (\is_array ($ data ) || ($ datainstanceof \Traversable && (null ===$ this ->serializer || !$ this ->serializer ->supportsNormalization ($ data ,$ this -> format )))) {
410+ if (\is_array ($ data ) || ($ datainstanceof \Traversable && (null ===$ this ->serializer || !$ this ->serializer ->supportsNormalization ($ data ,$ format )))) {
422411foreach ($ dataas $ key =>$ data ) {
423412//Ah this is the magic @ attribute types.
424413if (str_starts_with ($ key ,'@ ' ) &&$ this ->isElementNameValid ($ attributeName =substr ($ key ,1 ))) {
425414if (!is_scalar ($ data )) {
426- $ data =$ this ->serializer ->normalize ($ data ,$ this -> format ,$ this -> context );
415+ $ data =$ this ->serializer ->normalize ($ data ,$ format ,$ context );
427416 }
428417$ parentNode ->setAttribute ($ attributeName ,$ data );
429418 }elseif ('# ' ===$ key ) {
430- $ append =$ this ->selectNodeType ($ parentNode ,$ data );
419+ $ append =$ this ->selectNodeType ($ parentNode ,$ data, $ format , $ context );
431420 }elseif ('#comment ' ===$ key ) {
432421if (!\in_array (\XML_COMMENT_NODE ,$ encoderIgnoredNodeTypes ,true )) {
433422$ append =$ this ->appendComment ($ parentNode ,$ data );
@@ -441,15 +430,15 @@ private function buildXml(\DOMNode $parentNode, $data, string $xmlRootNodeName =
441430 * From ["item" => [0,1]];.
442431 */
443432foreach ($ dataas $ subData ) {
444- $ append =$ this ->appendNode ($ parentNode ,$ subData ,$ key );
433+ $ append =$ this ->appendNode ($ parentNode ,$ subData ,$ format , $ context , $ key );
445434 }
446435 }else {
447- $ append =$ this ->appendNode ($ parentNode ,$ data ,$ key );
436+ $ append =$ this ->appendNode ($ parentNode ,$ data ,$ format , $ context , $ key );
448437 }
449438 }elseif (is_numeric ($ key ) || !$ this ->isElementNameValid ($ key )) {
450- $ append =$ this ->appendNode ($ parentNode ,$ data ,'item ' ,$ key );
439+ $ append =$ this ->appendNode ($ parentNode ,$ data ,$ format , $ context , 'item ' ,$ key );
451440 }elseif (null !==$ data || !$ removeEmptyTags ) {
452- $ append =$ this ->appendNode ($ parentNode ,$ data ,$ key );
441+ $ append =$ this ->appendNode ($ parentNode ,$ data ,$ format , $ context , $ key );
453442 }
454443 }
455444
@@ -461,20 +450,20 @@ private function buildXml(\DOMNode $parentNode, $data, string $xmlRootNodeName =
461450throw new BadMethodCallException (sprintf ('The serializer needs to be set to allow "%s()" to be used with object data. ' ,__METHOD__ ));
462451 }
463452
464- $ data =$ this ->serializer ->normalize ($ data ,$ this -> format ,$ this -> context );
453+ $ data =$ this ->serializer ->normalize ($ data ,$ format ,$ context );
465454if (null !==$ data && !is_scalar ($ data )) {
466- return $ this ->buildXml ($ parentNode ,$ data ,$ xmlRootNodeName );
455+ return $ this ->buildXml ($ parentNode ,$ data ,$ format , $ context , $ xmlRootNodeName );
467456 }
468457
469458// top level data object was normalized into a scalar
470459if (!$ parentNode ->parentNode ->parentNode ) {
471460$ root =$ parentNode ->parentNode ;
472461$ root ->removeChild ($ parentNode );
473462
474- return $ this ->appendNode ($ root ,$ data ,$ xmlRootNodeName );
463+ return $ this ->appendNode ($ root ,$ data ,$ format , $ context , $ xmlRootNodeName );
475464 }
476465
477- return $ this ->appendNode ($ parentNode ,$ data ,'data ' );
466+ return $ this ->appendNode ($ parentNode ,$ data ,$ format , $ context , 'data ' );
478467 }
479468
480469throw new NotEncodableValueException ('An unexpected value could not be serialized: ' .(!\is_resource ($ data ) ?var_export ($ data ,true ) :sprintf ('%s resource ' ,get_resource_type ($ data ))));
@@ -485,13 +474,14 @@ private function buildXml(\DOMNode $parentNode, $data, string $xmlRootNodeName =
485474 *
486475 * @param array|object $data
487476 */
488- private function appendNode (\DOMNode $ parentNode ,$ data ,string $ nodeName ,string $ key =null ):bool
477+ private function appendNode (\DOMNode $ parentNode ,$ data ,string $ format , array $ context , string $ nodeName ,string $ key =null ):bool
489478 {
490- $ node =$ this ->dom ->createElement ($ nodeName );
479+ $ dom =$ parentNodeinstanceof \DomDocument ?$ parentNode :$ parentNode ->ownerDocument ;
480+ $ node =$ dom ->createElement ($ nodeName );
491481if (null !==$ key ) {
492482$ node ->setAttribute ('key ' ,$ key );
493483 }
494- $ appendNode =$ this ->selectNodeType ($ node ,$ data );
484+ $ appendNode =$ this ->selectNodeType ($ node ,$ data, $ format , $ context );
495485// we may have decided not to append this node, either in error or if its $nodeName is not valid
496486if ($ appendNode ) {
497487$ parentNode ->appendChild ($ node );
@@ -505,32 +495,32 @@ private function appendNode(\DOMNode $parentNode, $data, string $nodeName, strin
505495 */
506496private function needsCdataWrapping (string $ val ):bool
507497 {
508- return 0 < preg_match ('/[<>&]/ ' ,$ val );
498+ return preg_match ('/[<>&]/ ' ,$ val );
509499 }
510500
511501/**
512502 * Tests the value being passed and decide what sort of element to create.
513503 *
514504 * @throws NotEncodableValueException
515505 */
516- private function selectNodeType (\DOMNode $ node ,$ val ):bool
506+ private function selectNodeType (\DOMNode $ node ,$ val, string $ format , array $ context ):bool
517507 {
518508if (\is_array ($ val )) {
519- return $ this ->buildXml ($ node ,$ val );
509+ return $ this ->buildXml ($ node ,$ val, $ format , $ context );
520510 }elseif ($ valinstanceof \SimpleXMLElement) {
521- $ child =$ this -> dom ->importNode (dom_import_simplexml ($ val ),true );
511+ $ child =$ node -> ownerDocument ->importNode (dom_import_simplexml ($ val ),true );
522512$ node ->appendChild ($ child );
523513 }elseif ($ valinstanceof \Traversable) {
524- $ this ->buildXml ($ node ,$ val );
514+ $ this ->buildXml ($ node ,$ val, $ format , $ context );
525515 }elseif ($ valinstanceof \DOMNode) {
526- $ child =$ this -> dom ->importNode ($ val ,true );
516+ $ child =$ node -> ownerDocument ->importNode ($ val ,true );
527517$ node ->appendChild ($ child );
528518 }elseif (\is_object ($ val )) {
529519if (null ===$ this ->serializer ) {
530520throw new BadMethodCallException (sprintf ('The serializer needs to be set to allow "%s()" to be used with object data. ' ,__METHOD__ ));
531521 }
532522
533- return $ this ->selectNodeType ($ node ,$ this ->serializer ->normalize ($ val ,$ this -> format ,$ this -> context ));
523+ return $ this ->selectNodeType ($ node ,$ this ->serializer ->normalize ($ val ,$ format ,$ context ), $ format , $ context );
534524 }elseif (is_numeric ($ val )) {
535525return $ this ->appendText ($ node , (string )$ val );
536526 }elseif (\is_string ($ val ) &&$ this ->needsCdataWrapping ($ val )) {