我正在尝试使用yii2构建XML响应。但是我在itemtag
上有一些问题itemTag名称代表数字键的数组中的元素。示例
$itemTag = 'test';
return $response = ['tests' => [0 => 'a', 1 => 'b']];
XML结果
<response>
<tests>
<test>a</test>
<test>b</test>
</tests>
</response>
但是,当我想在测试中创建一个新组时,它仍然会获取itemTag名称。示例
return $response = ['tests' => [0 => 'a', 1 => 'b', 'days' => [0 => 'd1', 1 => 'd2']]];
这是XML结果
<response>
<tests>
<test>a</test>
<test>b</test>
<days>
<test>d1</test> // this should be day
<test>d2</test> // this should be day
</days>
</tests>
</response>
我该如何解决此问题?
让您的自定义xmlresponseformatter并覆盖此功能:
protected function buildXml($element, $data)
{
if (is_array($data)
|| ($data instanceof Traversable
&& $this->useTraversableAsArray
&& !$data instanceof Arrayable)
) {
foreach ($data as $name => $value) {
if(is_array($value) && $this->checkArrayKeyNumber($value)){
foreach ($value as $number => $childValue) {
$ele = new DOMElement($name);
$element->insertBefore(
$element->ownerDocument->createTextNode("n")
);
$element->appendChild($ele);
$this->buildXml($ele, $childValue);
}
continue;
}
if (is_int($name) && is_object($value)) {
$this->buildXml($element, $value);
} elseif (is_array($value) || is_object($value)) {
$child = new DOMElement($this->getValidXmlElementName($name));
$element->insertBefore(
$element->ownerDocument->createTextNode("n")
);
$element->appendChild($child);
$this->buildXml($child, $value);
} else {
$child = new DOMElement($this->getValidXmlElementName($name));
$element->insertBefore(
$element->ownerDocument->createTextNode("n")
);
$element->appendChild($child);
$child->appendChild(
new DOMText($this->formatScalarValue($value))
);
}
}
} elseif (is_object($data)) {
if ($this->useObjectTags) {
$child = new DOMElement(StringHelper::basename(get_class($data)));
$element->appendChild($child);
} else {
$child = $element;
}
if ($data instanceof Arrayable) {
$this->buildXml($child, $data->toArray());
} else {
$array = [];
foreach ($data as $name => $value) {
$array[$name] = $value;
}
$this->buildXml($child, $array);
}
} else {
$element->appendChild(new DOMText($this->formatScalarValue($data)));
}
$element->insertBefore(
$element->ownerDocument->createTextNode("n")
);
}
添加新功能以检查数字数据的位置是数字的,例如
[
'days' =>
[
0 => 'd1',
1 => 'd2'
]
]
此功能
private function checkArrayKeyNumber($array)
{
$keys = array_keys($array);
$numeric = true;
foreach ($keys as $key) {
if(!is_numeric($key)){
$numeric = false;
}
}
return $numeric;
}
最后,添加到您的自定义响应类init((
public function init()
{
parent::init();
$this->formatters['xml']
= 'pathtoyourcustomXmlResponseFormatter';
}