我有一个将数组转换为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>
实际上,我会根据accept标头返回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
答案 0 :(得分:1)
如果您不想修改现有功能,则可以使用以下内容:
$xml = new \SimpleXMLElement('<?xml version="1.0"?><offices></offices>');
$first = array("id" => 1, "name" => "firstOffice");
$second = array("id" => 2, "name" => "secondOffice");
array_to_xml(array("office" => $first), $xml);
array_to_xml(array("office" => $second), $xml);
echo $xml->asXML();
该函数假定如果您只传入一个数组,则希望它们分组为itemX标记。如果您需要单独的办公室标签,则需要为每个办公室多次调用该功能。