Yii2 xml XmlResponseFormatter



我正在尝试使用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';
}

相关内容

  • 没有找到相关文章

最新更新