如何在 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');
我使用 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');