Completed
Pull Request — master (#859)
by
unknown
05:02
created

XmlSerializationVisitor   D

Complexity

Total Complexity 119

Size/Duplication

Total Lines 502
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 89.67%

Importance

Changes 0
Metric Value
wmc 119
lcom 1
cbo 10
dl 0
loc 502
ccs 243
cts 271
cp 0.8967
rs 4.8717
c 0
b 0
f 0

41 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A setDefaultRootName() 0 5 1
A hasDefaultRootName() 0 4 1
A setDefaultVersion() 0 4 1
A setDefaultEncoding() 0 4 1
A setNavigator() 0 7 1
A getNavigator() 0 4 1
A visitNull() 0 19 2
B visitString() 0 18 5
A visitSimpleString() 0 11 2
A visitBoolean() 0 11 4
A visitInteger() 0 4 1
A visitDouble() 0 4 1
F visitArray() 0 33 16
B startVisitingObject() 0 27 5
D visitProperty() 0 100 28
A isInLineCollection() 0 4 2
A isCircularRef() 0 4 1
A isSkippableEmptyObject() 0 4 3
A isSkippableCollection() 0 4 2
A isElementEmpty() 0 4 2
A endVisitingObject() 0 4 1
A getResult() 0 4 1
A getCurrentNode() 0 4 1
A getCurrentMetadata() 0 4 1
A getDocument() 0 4 1
A setCurrentMetadata() 0 5 1
A setCurrentNode() 0 5 1
A revertCurrentNode() 0 4 1
A revertCurrentMetadata() 0 4 1
B createDocument() 0 17 5
A prepare() 0 6 1
A visitNumeric() 0 11 2
A isElementNameValid() 0 4 3
A attachNullNamespace() 0 11 2
A addNamespaceAttributes() 0 12 4
B createElement() 0 13 5
A setAttributeOnNode() 0 11 3
A getClassDefaultNamespace() 0 4 2
A isFormatOutput() 0 4 1
A setFormatOutput() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like XmlSerializationVisitor often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use XmlSerializationVisitor, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * Copyright 2016 Johannes M. Schmitt <[email protected]>
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace JMS\Serializer;
20
21
use JMS\Serializer\Accessor\AccessorStrategyInterface;
22
use JMS\Serializer\Exception\RuntimeException;
23
use JMS\Serializer\Metadata\ClassMetadata;
24
use JMS\Serializer\Metadata\PropertyMetadata;
25
use JMS\Serializer\Naming\AdvancedNamingStrategyInterface;
26
use JMS\Serializer\Naming\PropertyNamingStrategyInterface;
27
28
/**
29
 * XmlSerializationVisitor.
30
 *
31
 * @author Johannes M. Schmitt <[email protected]>
32
 */
33
class XmlSerializationVisitor extends AbstractVisitor
34
{
35
    public $document;
36
37
    private $navigator;
38
    private $defaultRootName = 'result';
39
    private $defaultRootNamespace;
40
    private $defaultVersion = '1.0';
41
    private $defaultEncoding = 'UTF-8';
42
    private $stack;
43
    private $metadataStack;
44
    private $currentNode;
45
    private $currentMetadata;
46
    private $hasValue;
47
    private $nullWasVisited;
48
    private $objectMetadataStack;
49
50
    /** @var boolean */
51
    private $formatOutput;
52
53 384
    public function __construct(
54
        PropertyNamingStrategyInterface $namingStrategy,
55
        AccessorStrategyInterface $accessorStrategy = null,
56
        AdvancedNamingStrategyInterface $advancedNamingStrategy = null
57
    ) {
58 384
        parent::__construct($namingStrategy, $accessorStrategy, $advancedNamingStrategy);
59 384
        $this->objectMetadataStack = new \SplStack;
60 384
        $this->formatOutput = true;
61 384
    }
62
63
    public function setDefaultRootName($name, $namespace = null)
64
    {
65
        $this->defaultRootName = $name;
66
        $this->defaultRootNamespace = $namespace;
67
    }
68
69
    /**
70
     * @return boolean
71
     */
72
    public function hasDefaultRootName()
73
    {
74
        return 'result' === $this->defaultRootName;
75
    }
76
77
    public function setDefaultVersion($version)
78
    {
79
        $this->defaultVersion = $version;
80
    }
81
82
    public function setDefaultEncoding($encoding)
83
    {
84
        $this->defaultEncoding = $encoding;
85
    }
86
87 107
    public function setNavigator(GraphNavigator $navigator)
88
    {
89 107
        $this->navigator = $navigator;
90 107
        $this->document = null;
91 107
        $this->stack = new \SplStack;
92 107
        $this->metadataStack = new \SplStack;
93 107
    }
94
95
    public function getNavigator()
96
    {
97
        return $this->navigator;
98
    }
99
100 9
    public function visitNull($data, array $type, Context $context)
101
    {
102 9
        if (null === $this->document) {
103 6
            $this->document = $this->createDocument(null, null, true);
104 6
            $node = $this->document->createAttribute('xsi:nil');
105 6
            $node->value = 'true';
106 6
            $this->currentNode->appendChild($node);
107
108 6
            $this->attachNullNamespace();
109
110 6
            return;
111
        }
112
113 3
        $node = $this->document->createAttribute('xsi:nil');
0 ignored issues
show
Bug introduced by
The method createAttribute cannot be called on $this->document (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
114 3
        $node->value = 'true';
115 3
        $this->attachNullNamespace();
116
117 3
        return $node;
118
    }
119
120 73
    public function visitString($data, array $type, Context $context)
121
    {
122
123 73
        if (null !== $this->currentMetadata) {
124 65
            $doCData = $this->currentMetadata->xmlElementCData;
125 65
        } else {
126 9
            $doCData = true;
127
        }
128
129 73
        if (null === $this->document) {
130 5
            $this->document = $this->createDocument(null, null, true);
131 5
            $this->currentNode->appendChild($doCData ? $this->document->createCDATASection($data) : $this->document->createTextNode((string)$data));
132
133 5
            return;
134
        }
135
136 68
        return $doCData ? $this->document->createCDATASection($data) : $this->document->createTextNode((string)$data);
0 ignored issues
show
Bug introduced by
The method createCDATASection cannot be called on $this->document (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
137
    }
138
139 2
    public function visitSimpleString($data, array $type, Context $context)
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $context is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
140
    {
141 2
        if (null === $this->document) {
142 2
            $this->document = $this->createDocument(null, null, true);
143 2
            $this->currentNode->appendChild($this->document->createTextNode((string)$data));
144
145 2
            return;
146
        }
147
148
        return $this->document->createTextNode((string)$data);
149
    }
150
151 5
    public function visitBoolean($data, array $type, Context $context)
152
    {
153 5
        if (null === $this->document) {
154 2
            $this->document = $this->createDocument(null, null, true);
155 2
            $this->currentNode->appendChild($this->document->createTextNode($data ? 'true' : 'false'));
156
157 2
            return;
158
        }
159
160 3
        return $this->document->createTextNode($data ? 'true' : 'false');
161
    }
162
163 19
    public function visitInteger($data, array $type, Context $context)
164
    {
165 19
        return $this->visitNumeric($data, $type);
166
    }
167
168 9
    public function visitDouble($data, array $type, Context $context)
169
    {
170 9
        return $this->visitNumeric($data, $type);
171
    }
172
173 28
    public function visitArray($data, array $type, Context $context)
174
    {
175 28
        if (null === $this->document) {
176 9
            $this->document = $this->createDocument(null, null, true);
177 9
        }
178
179 28
        $entryName = (null !== $this->currentMetadata && null !== $this->currentMetadata->xmlEntryName) ? $this->currentMetadata->xmlEntryName : 'entry';
180 28
        $keyAttributeName = (null !== $this->currentMetadata && null !== $this->currentMetadata->xmlKeyAttribute) ? $this->currentMetadata->xmlKeyAttribute : null;
181 28
        $namespace = (null !== $this->currentMetadata && null !== $this->currentMetadata->xmlEntryNamespace) ? $this->currentMetadata->xmlEntryNamespace : null;
182
183 28
        foreach ($data as $k => $v) {
184
185 27
            if (null === $v && $context->shouldSerializeNull() !== true) {
186 1
                continue;
187
            }
188
189 27
            $tagName = (null !== $this->currentMetadata && $this->currentMetadata->xmlKeyValuePairs && $this->isElementNameValid($k)) ? $k : $entryName;
190
191 27
            $entryNode = $this->createElement($tagName, $namespace);
192 27
            $this->currentNode->appendChild($entryNode);
193 27
            $this->setCurrentNode($entryNode);
194
195 27
            if (null !== $keyAttributeName) {
196 7
                $entryNode->setAttribute($keyAttributeName, (string)$k);
197 7
            }
198
199 27
            if (null !== $node = $this->navigator->accept($v, $this->getElementType($type), $context)) {
200 18
                $this->currentNode->appendChild($node);
201 18
            }
202
203 27
            $this->revertCurrentNode();
204 28
        }
205 28
    }
206
207 73
    public function startVisitingObject(ClassMetadata $metadata, $data, array $type, Context $context)
208
    {
209 73
        $this->objectMetadataStack->push($metadata);
210
211 73
        if (null === $this->document) {
212 71
            $this->document = $this->createDocument(null, null, false);
213 71
            if ($metadata->xmlRootName) {
214 19
                $rootName = $metadata->xmlRootName;
215 19
                $rootNamespace = $metadata->xmlRootNamespace ?: $this->getClassDefaultNamespace($metadata);
216 19
            } else {
217 52
                $rootName = $this->defaultRootName;
218 52
                $rootNamespace = $this->defaultRootNamespace;
219
            }
220
221 71
            if ($rootNamespace) {
222 7
                $this->currentNode = $this->document->createElementNS($rootNamespace, $rootName);
223 7
            } else {
224 64
                $this->currentNode = $this->document->createElement($rootName);
225
            }
226
227 71
            $this->document->appendChild($this->currentNode);
228 71
        }
229
230 73
        $this->addNamespaceAttributes($metadata, $this->currentNode);
231
232 73
        $this->hasValue = false;
233 73
    }
234
235 73
    public function visitProperty(PropertyMetadata $metadata, $object, Context $context)
236
    {
237 73
        $v = $this->accessor->getValue($object, $metadata);
238
239 72
        if (null === $v && $context->shouldSerializeNull() !== true) {
240 8
            return;
241
        }
242
243 72
        if ($metadata->xmlAttribute) {
244 12
            $this->setCurrentMetadata($metadata);
245 12
            $node = $this->navigator->accept($v, $metadata->type, $context);
246 12
            $this->revertCurrentMetadata();
247
248 12
            if (!$node instanceof \DOMCharacterData) {
249
                throw new RuntimeException(sprintf('Unsupported value for XML attribute for %s. Expected character data, but got %s.', $metadata->name, json_encode($v)));
250
            }
251 12
            $attributeName = $this->namingStrategy->translateName($metadata);
252 12
            if ($this->hasAdvancedNamingStrategy()) {
253
                $attributeName = $this->advancedNamingStrategy->translateName($metadata, $context);
254
            }
255 12
            $this->setAttributeOnNode($this->currentNode, $attributeName, $node->nodeValue, $metadata->xmlNamespace);
256
257 12
            return;
258
        }
259
260 70
        if (($metadata->xmlValue && $this->currentNode->childNodes->length > 0)
261 70
            || (!$metadata->xmlValue && $this->hasValue)
262 70
        ) {
263 1
            throw new RuntimeException(sprintf('If you make use of @XmlValue, all other properties in the class must have the @XmlAttribute annotation. Invalid usage detected in class %s.', $metadata->class));
264
        }
265
266 70
        if ($metadata->xmlValue) {
267 8
            $this->hasValue = true;
268
269 8
            $this->setCurrentMetadata($metadata);
270 8
            $node = $this->navigator->accept($v, $metadata->type, $context);
271 8
            $this->revertCurrentMetadata();
272
273 8
            if (!$node instanceof \DOMCharacterData) {
274
                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)));
275
            }
276
277 8
            $this->currentNode->appendChild($node);
278
279 8
            return;
280
        }
281
282 66
        if ($metadata->xmlAttributeMap) {
283 2
            if (!is_array($v)) {
284 1
                throw new RuntimeException(sprintf('Unsupported value type for XML attribute map. Expected array but got %s.', gettype($v)));
285
            }
286
287 1
            foreach ($v as $key => $value) {
288 1
                $this->setCurrentMetadata($metadata);
289 1
                $node = $this->navigator->accept($value, null, $context);
290 1
                $this->revertCurrentMetadata();
291
292 1
                if (!$node instanceof \DOMCharacterData) {
293
                    throw new RuntimeException(sprintf('Unsupported value for a XML attribute map value. Expected character data, but got %s.', json_encode($v)));
294
                }
295
296 1
                $this->setAttributeOnNode($this->currentNode, $key, $node->nodeValue, $metadata->xmlNamespace);
297 1
            }
298
299 1
            return;
300
        }
301
302 64
        if ($addEnclosingElement = !$this->isInLineCollection($metadata) && !$metadata->inline) {
0 ignored issues
show
Comprehensibility introduced by
Consider adding parentheses for clarity. Current Interpretation: $addEnclosingElement = (... && !$metadata->inline), Probably Intended Meaning: ($addEnclosingElement = ...) && !$metadata->inline
Loading history...
303 63
            $elementName = $this->namingStrategy->translateName($metadata);
304 63
            if ($this->hasAdvancedNamingStrategy()) {
305
                $elementName = $this->advancedNamingStrategy->translateName($metadata, $context);
306
            }
307
308 63
            $namespace = null !== $metadata->xmlNamespace
309 63
                ? $metadata->xmlNamespace
310 63
                : $this->getClassDefaultNamespace($this->objectMetadataStack->top());
311
312 63
            $element = $this->createElement($elementName, $namespace);
313 63
            $this->currentNode->appendChild($element);
314 63
            $this->setCurrentNode($element);
315 63
        }
316
317 64
        $this->setCurrentMetadata($metadata);
318
319 64
        if (null !== $node = $this->navigator->accept($v, $metadata->type, $context)) {
320 53
            $this->currentNode->appendChild($node);
321 53
        }
322
323 64
        $this->revertCurrentMetadata();
324
325 64
        if ($addEnclosingElement) {
326 63
            $this->revertCurrentNode();
327
328 63
            if ($this->isElementEmpty($element) && ($v === null || $this->isSkippableCollection($metadata) || $this->isSkippableEmptyObject($node, $metadata) || $this->isCircularRef($context, $v))) {
0 ignored issues
show
Compatibility introduced by
$context of type object<JMS\Serializer\Context> is not a sub-type of object<JMS\Serializer\SerializationContext>. It seems like you assume a child class of the class JMS\Serializer\Context to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
329 5
                $this->currentNode->removeChild($element);
0 ignored issues
show
Bug introduced by
The variable $element does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
330 5
            }
331 63
        }
332
333 64
        $this->hasValue = false;
334 64
    }
335
336 64
    private function isInLineCollection(PropertyMetadata $metadata)
337
    {
338 64
        return $metadata->xmlCollection && $metadata->xmlCollectionInline;
339
    }
340
341 4
    private function isCircularRef(SerializationContext $context, $v)
342
    {
343 4
        return $context->isVisiting($v);
344
    }
345
346 6
    private function isSkippableEmptyObject($node, PropertyMetadata $metadata)
347
    {
348 6
        return $node === null && !$metadata->xmlCollection && $metadata->skipWhenEmpty;
349
    }
350
351 7
    private function isSkippableCollection(PropertyMetadata $metadata)
352
    {
353 7
        return $metadata->xmlCollection && $metadata->xmlCollectionSkipWhenEmpty;
354
    }
355
356 63
    private function isElementEmpty(\DOMElement $element)
357
    {
358 63
        return !$element->hasChildNodes() && !$element->hasAttributes();
359
    }
360
361 70
    public function endVisitingObject(ClassMetadata $metadata, $data, array $type, Context $context)
362
    {
363 70
        $this->objectMetadataStack->pop();
364 70
    }
365
366 102
    public function getResult()
367
    {
368 102
        return $this->document->saveXML();
369
    }
370
371 2
    public function getCurrentNode()
372
    {
373 2
        return $this->currentNode;
374
    }
375
376
    public function getCurrentMetadata()
377
    {
378
        return $this->currentMetadata;
379
    }
380
381
    public function getDocument()
382
    {
383
        return $this->document;
384
    }
385
386 71
    public function setCurrentMetadata(PropertyMetadata $metadata)
387
    {
388 71
        $this->metadataStack->push($this->currentMetadata);
389 71
        $this->currentMetadata = $metadata;
390 71
    }
391
392 95
    public function setCurrentNode(\DOMNode $node)
393
    {
394 95
        $this->stack->push($this->currentNode);
395 95
        $this->currentNode = $node;
396 95
    }
397
398 71
    public function revertCurrentNode()
399
    {
400 71
        return $this->currentNode = $this->stack->pop();
401
    }
402
403 71
    public function revertCurrentMetadata()
404
    {
405 71
        return $this->currentMetadata = $this->metadataStack->pop();
406
    }
407
408 105
    public function createDocument($version = null, $encoding = null, $addRoot = true)
409
    {
410 105
        $doc = new \DOMDocument($version ?: $this->defaultVersion, $encoding ?: $this->defaultEncoding);
411 105
        $doc->formatOutput = $this->isFormatOutput();
412
413 105
        if ($addRoot) {
414 30
            if ($this->defaultRootNamespace) {
415
                $rootNode = $doc->createElementNS($this->defaultRootNamespace, $this->defaultRootName);
416
            } else {
417 30
                $rootNode = $doc->createElement($this->defaultRootName);
418
            }
419 30
            $this->setCurrentNode($rootNode);
420 30
            $doc->appendChild($rootNode);
421 30
        }
422
423 105
        return $doc;
424
    }
425
426 107
    public function prepare($data)
427
    {
428 107
        $this->nullWasVisited = false;
429
430 107
        return $data;
431
    }
432
433 28
    private function visitNumeric($data, array $type)
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
434
    {
435 28
        if (null === $this->document) {
436 5
            $this->document = $this->createDocument(null, null, true);
437 5
            $this->currentNode->appendChild($textNode = $this->document->createTextNode((string)$data));
438
439 5
            return $textNode;
440
        }
441
442 23
        return $this->document->createTextNode((string)$data);
443
    }
444
445
    /**
446
     * Checks that the name is a valid XML element name.
447
     *
448
     * @param string $name
449
     *
450
     * @return boolean
451
     */
452 2
    private function isElementNameValid($name)
453
    {
454 2
        return $name && false === strpos($name, ' ') && preg_match('#^[\pL_][\pL0-9._-]*$#ui', $name);
455
    }
456
457 9
    private function attachNullNamespace()
458
    {
459 9
        if (!$this->nullWasVisited) {
460 9
            $this->document->documentElement->setAttributeNS(
461 9
                'http://www.w3.org/2000/xmlns/',
462 9
                'xmlns:xsi',
463
                'http://www.w3.org/2001/XMLSchema-instance'
464 9
            );
465 9
            $this->nullWasVisited = true;
466 9
        }
467 9
    }
468
469
    /**
470
     * Adds namespace attributes to the XML root element
471
     *
472
     * @param \JMS\Serializer\Metadata\ClassMetadata $metadata
473
     * @param \DOMElement $element
474
     */
475 73
    private function addNamespaceAttributes(ClassMetadata $metadata, \DOMElement $element)
476
    {
477 73
        foreach ($metadata->xmlNamespaces as $prefix => $uri) {
478 9
            $attribute = 'xmlns';
479 9
            if ($prefix !== '') {
480 9
                $attribute .= ':' . $prefix;
481 9
            } elseif ($element->namespaceURI === $uri) {
482 4
                continue;
483
            }
484 9
            $element->setAttributeNS('http://www.w3.org/2000/xmlns/', $attribute, $uri);
485 73
        }
486 73
    }
487
488 71
    private function createElement($tagName, $namespace = null)
489
    {
490 71
        if (null === $namespace) {
491 65
            return $this->document->createElement($tagName);
492
        }
493 9
        if ($this->currentNode->isDefaultNamespace($namespace)) {
494 5
            return $this->document->createElementNS($namespace, $tagName);
495
        }
496 9
        if (!($prefix = $this->currentNode->lookupPrefix($namespace)) && !($prefix = $this->document->lookupPrefix($namespace))) {
497 3
            $prefix = 'ns-' . substr(sha1($namespace), 0, 8);
498 3
        }
499 9
        return $this->document->createElementNS($namespace, $prefix . ':' . $tagName);
500
    }
501
502 13
    private function setAttributeOnNode(\DOMElement $node, $name, $value, $namespace = null)
503
    {
504 13
        if (null !== $namespace) {
505 4
            if (!$prefix = $node->lookupPrefix($namespace)) {
506 2
                $prefix = 'ns-' . substr(sha1($namespace), 0, 8);
507 2
            }
508 4
            $node->setAttributeNS($namespace, $prefix . ':' . $name, $value);
509 4
        } else {
510 11
            $node->setAttribute($name, $value);
511
        }
512 13
    }
513
514 62
    private function getClassDefaultNamespace(ClassMetadata $metadata)
515
    {
516 62
        return (isset($metadata->xmlNamespaces['']) ? $metadata->xmlNamespaces[''] : null);
517
    }
518
519
    /**
520
     * @return bool
521
     */
522 105
    public function isFormatOutput()
523
    {
524 105
        return $this->formatOutput;
525
    }
526
527
    /**
528
     * @param bool $formatOutput
529
     */
530 1
    public function setFormatOutput($formatOutput)
531
    {
532 1
        $this->formatOutput = (boolean)$formatOutput;
533 1
    }
534
}
535