【发布时间】:2017-06-14 08:45:52
【问题描述】:
我有一个将数组转换为 XML 的函数,但它在任何情况下都不起作用。
public function array_to_xml($data, &$xml_data) {
foreach($data as $key => $value) {
if (is_numeric($key)) {
$key = 'item'.$key;
}
if (is_array($value)) {
$subnode = $xml_data->addChild($key);
$this->array_to_xml($value, $subnode);
} else {
$xml_data->addChild("$key",htmlspecialchars("$value"));
}
}
}
但是如果我发送这个数组,它将返回<item0...n>:
$xml = new \SimpleXMLElement('<?xml version="1.0"?><offices></offices>');
$first = array("id" => 1, "name" => "firstOffice");
$second = array("id" => 2, "name" => "secondOffice");
$offices = array("office" => array($first, $second));
return array_to_xml($data, $xml);
输出
<offices>
<office>
<item0>
<id>1</id>
<name>firstOffice</name>
</item0>
<item1>
<id>2</id>
<name>secondOffice</name>
</item1>
</office>
</offices>
如何编辑我的函数以获得此结果:
<offices>
<office>
<id>1</id>
<name>firstOffice</name>
</office>
<office>
<id>2</id>
<name>secondOffice</name>
</office>
</offices>
实际上,我将根据接受标头返回 JSON 或 XML,然后我必须为 JSON 和 XML 使用相同的数组。
这是我当前代码的一部分:
public function getOffices() {
$tools = new Tools();
$accept = $this->request->getHeader('accept');
$xml = new \SimpleXMLElement('<?xml version="1.0"?><offices></offices>');
$offices = Offices::find(); // Find all offices, I'm using Phalcon PHP ORM
return $tools->formatAdapter($accept, array("office" => $offices->toArray()), 200, $xml);
}
工具函数类
public function array_to_xml($data, &$xml_data) {
foreach($data as $key => $value) {
if (is_numeric($key)) {
$key = 'item'.$key;
}
if (is_array($value)) {
$subnode = $xml_data->addChild($key);
$this->array_to_xml($value, $subnode);
} else {
$xml_data->addChild("$key",htmlspecialchars("$value"));
}
}
}
public function formatAdapter($type, $data, $code, &$xml_data) {
if ($type == 'application/json') {
return $this->JSONBuilder($data, $code);
} else {
$this->array_to_xml($data, $xml_data);
return $this->XMLBuilder($xml_data->asXML(), $code);
}
}
public function JSONBuilder($data, $code) {
$response = new Response();
$message = $this->getResponseDescription($code);
$response->setHeader('Content-Type', 'application/json');
$response->setStatusCode($code, $message);
$response->setJsonContent($data);
return $response;
}
function XMLBuilder($xml, $code) {
$response = new Response();
$message = $this->getResponseDescription($code);
$response->setHeader('Content-Type', 'application/xml');
$response->setStatusCode($code, $message);
$response->setContent($xml);
return $response;
}
编辑 formatAdapter 函数
public function formatAdapter($type, $data, $code, &$xml_data, $loop = false) {
if ($type == 'application/json') {
return $this->JSONBuilder($data, $code);
} else {
if ($loop) {
foreach ($data as $key => $value) {
foreach ($value as $obj) {
$this->array_to_xml(array($key => $obj), $xml_data);
}
}
} else {
$this->array_to_xml($data, $xml_data);
}
return $this->XMLBuilder($xml_data->asXML(), $code);
}
}
如果我在我的函数和 $loop 参数中添加这个循环,它就会起作用。但正如你所看到的,我有 2 个 foreach 循环。可以避免第一个 foreach 循环吗?因为我每次都会循环一次。我尝试使用 array_value() 但它不起作用。
编辑修复
最后我找到了我的 formatAdapter 函数的解决方案,但它只适用于第一个对象。如果有人有更好的解决方案:
public function formatAdapter($type, $data, $code, &$xml_data, $loop = false) {
if ($type == 'application/json') {
return $this->JSONBuilder($data, $code);
} else {
if ($loop) {
$key = key($data);
foreach ($data[$key] as $obj) {
$this->array_to_xml(array($key => $obj), $xml_data);
}
} else {
$this->array_to_xml($data, $xml_data);
}
return $this->XMLBuilder($xml_data->asXML(), $code);
}
}
感谢@iainn
【问题讨论】:
-
不确定我是否理解这个问题。而不是第一个输出,您有兴趣获得第二个输出?
-
是的。 item0, item1 不明确。我需要指定对象名称。这里我有一系列办公室,然后我想为每个办公室写
<office> -
但是你正在运行 'foreach' $key = 'item'.$key; ...?
-
是的,我必须用前一个键替换这一行,但我不知道如何