I use Symfony 3 Serializer and convert my objects to XML through XmlEncoder. But XmlEncoder don't have encoding type in xml prolog. How to solve this problem?
Can I add custom attribut with parameters after root element?
Is there any way to set xmlns in root element?
I need such XML output:
<?xml version="1.0" encoding="utf-8"?>
<realty-feed xmlns="http://webmaster.yandex.ru/schemas/feed/realty/2010-06">
<generation-date>2010-10-05T16:36:00+04:00</generation-date>
...
</realty-feed>
Now I get this:
<?xml version="1.0"?>
<realty-feed>
...
</realty-feed>
My serializer code fragment:
$xmlEncoder = new XmlEncoder('realty-feed');
$normalizer = new CustomNormalizer();
$serializer = new Serializer(array($normalizer),array($xmlEncoder));
$output = $serializer->serialize($objectData, 'xml');
I solved my problem. I created my own class and write the same methods as in default class XmlEncoder with some changes in few standart public and private methods.
class N1XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, DecoderInterface, NormalizationAwareInterface
{
...
/**
* {@inheritdoc}
*/
public function encode($data, $format, array $context = array())
{
if ($data instanceof \DOMDocument) {
return $data->saveXML();
}
$xmlRootNodeName = $this->resolveXmlRootName($context);
$this->dom = $this->createDomDocument($context);
$this->format = $format;
$this->context = $context;
if (null !== $data && !is_scalar($data)) {
$root = $this->dom->createElementNS('http://webmaster.yandex.ru/schemas/feed/realty/2010-06', $xmlRootNodeName);
$dateTime = new \DateTime('now');
$dateTimeStr = $dateTime->format(DATE_ATOM);
$rootDate = $this->dom->createElement('generation-date', $dateTimeStr);
$this->dom->appendChild($root);
$root->appendChild($rootDate);
$this->buildXml($root, $data, $xmlRootNodeName);
} else {
$this->appendNode($this->dom, $data, $xmlRootNodeName);
}
return $this->dom->saveXML();
}
...
private function createDomDocument(array $context)
{
$document = new \DOMDocument('1.0','utf-8');
// Set an attribute on the DOM document specifying, as part of the XML declaration,
$xmlOptions = array(
// nicely formats output with indentation and extra space
'xml_format_output' => 'formatOutput',
// the version number of the document
'xml_version' => 'xmlVersion',
// the encoding of the document
'xml_encoding' => 'encoding',
// whether the document is standalone
'xml_standalone' => 'xmlStandalone',
);
foreach ($xmlOptions as $xmlOption => $documentProperty) {
if (isset($context[$xmlOption])) {
$document->$documentProperty = $context[$xmlOption];
}
}
return $document;
}