如何在 Symfony XmlEncoder 中设置编码 UTF-8 和 xmlns 属性

How set encoding UTF-8 and the xmlns attribute in Symfony XmlEncoder

我使用 Symfony 3 Serializer 并通过 XmlEncoder 将我的对象转换为 XML。但是 XmlEncoder 在 xml 序言中没有编码类型。如何解决这个问题?

我可以在根元素后添加带有参数的自定义属性吗?

有什么方法可以在根元素中设置 xmlns 吗?

我需要这样的 XML 输出:

<?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>

现在我明白了:

<?xml version="1.0"?>
<realty-feed>
...
</realty-feed>

我的序列化程序代码片段:

$xmlEncoder = new XmlEncoder('realty-feed');
$normalizer = new CustomNormalizer();
$serializer = new Serializer(array($normalizer),array($xmlEncoder));
$output = $serializer->serialize($objectData, 'xml');

我解决了我的问题。 我创建了自己的 class 并编写了与默认 class XmlEncoder 中相同的方法,但对一些标准 public 和私有方法进行了一些更改。

    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;
    }
<?php
$xmlEncoder = new XmlEncoder('realty-feed');
$xml = $xmlEncoder->encode([
    '@xmlns'          => 'http://webmaster.yandex.ru/schemas/feed/realty/2010-06',
    'generation-date' => '2010-10-05T16:36:00+04:00',
], 'xml');
echo $xml;

首先创建具有根节点名称的 Xml 编码器(在您的情况下为 "realty-feed"):

$encoder = new XmlEncoder("realty-feed");

比生成 Xml 文件:

$xml = $encoder->encode([], 'xml', ['xml_encoding' => 'utf-8']);

其中第一个参数: - 数组 xml 结构和数据

第二: - 格式

第三个: - 上下文属性(在你的情况下 xml_enxoding)

UPD:

为 xls 根元素设置属性的方法。工作完美。 !考虑 return 类型提示(仅适用于 PHP 7+)

/**
 * Add params to xml root element
 *
 * @param $xml
 * @return SimpleXMLElement
 */
private function setXmlParams(SimpleXMLElement $xml): SimpleXMLElement
{
    $xml = new \SimpleXMLElement($xml);
    $xml->addAttribute('xmlns:xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance");
    $xml->addAttribute('xmlns:xmlns:xsd', "http://www.w3.org/2001/XMLSchema");
    $xml->addAttribute('xmlns', "http://localhost/example");

    return $xml;
}

输出根元素:

<Root 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     xmlns="http://localhost/example"
>

{"symfony/serializer": "^5.0"} 版本中,我可以通过以下方式添加这些属性:

$encoder = new XmlEncoder();
$nodes = ['@xmlns' => 'http://webmaster.yandex.ru/schemas/feed/realty/2010-06',
          'generation-date' => '2010-10-05T16:36:00+04:00'];
$xmlString = $encoder->encode($nodes, 'xml', [
    XmlEncoder::ROOT_NODE_NAME => 'realty-feed',
    XmlEncoder::ENCODING       => 'UTF-8',
]); 
echo $xmlString;

还尝试了以下方法,但无效:

$encoder = new XmlEncoder([
XmlEncoder::ROOT_NODE_NAME => $rootNodeName,
XmlEncoder::ENCODING       => $encoding,
'@xmlns' => 'http://webmaster.yandex.ru/schemas/feed/realty/2010-06',
]);

echo $encoder->encode($nodes, 'xml');