2013-05-09 56 views
0

我试图让PHP将嵌套数组转换成XML文档。我一直无法解决为什么没有孩子的数组完全隐藏在XML输出中;我希望他们在XML中也没有孩子。为什么空数组在输出为XML时被隐藏?

下面是相关的代码片段:

private function response_xml_encode($node, $data) 
{ 
    if ($node == null) return false; 
    if (!is_array($data)) return false; 
    foreach ($data as $key => $value) 
    { 
    if (is_array($value) && !$this->response_xml_encode_assocarray($value)) 
    { 
     foreach ($value as $val) 
     $node->addChild($key, htmlentities($val)); 
    } 
    else if (is_array($value)) 
    { 
     $this->response_xml_encode($node->addChild($key), $value); 
    } 
    else if (!$this->response_xml_encode_validkey($key)) 
    { 
     $subnode = $node->addChild($node->getName(), htmlentities($value)); 
     $subnode->addAttribute('keyinvalid', 'true'); 
     $subnode->addAttribute('key', htmlentities($key)); 
    } 
    else 
    { 
     $node->addChild($key, htmlentities($value)); 
    } 
    } 
} 

private function response_xml_encode_assocarray($arr) 
{ 
    // Let's us know if this array has associative key value pairs, or if it has numeric key value pairs 
    // Returns TRUE if this array has any non-numeric key in it 
    foreach ($arr as $key => $value) 
    { 
    if (!is_numeric($key)) return true; 
    } 
    return false; 
} 

private function response_xml_encode_validkey($key) 
{ 
    if (strpos('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_', substr($key, 0, 1)) === false) return false; 
    return (preg_match('/[^A-Za-z_-]/s', $key) === 0); 
} 

我然后使用叫它:

$response = array(
    'result' => 0, 
    'message' => 'Success.', 
    'function' => 'test', 
    'data' => array(
    'GET' => $_GET, 
    'POST' => $_POST, 
    'foo' => array(
     'bar' => array(
     'bad' => array(
      'wolf' => array(
      'some_value' => 'testtesttest' 
     ) 
     ) 
    ) 
    ) 
) 
); 
$root = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><response/>'); 
$this->response_xml_encode($root, $response); 
return $root->asXML(); 

注意$_GET$_POST是空数组。

下面就是获取返回:

<?xml version="1.0" encoding="UTF-8"?> 
<response> 
    <result>0</result> 
    <message>Success.</message> 
    <function>test</function> 
    <data> 
    <foo> 
     <bar> 
     <bad> 
      <wolf> 
      <some_value>testtesttest</some_value> 
      </wolf> 
     </bad> 
     </bar> 
    </foo> 
    </data> 
</response> 

但有什么期望是它显示<GET/><POST/>它显示<foo>前:

<?xml version="1.0" encoding="UTF-8"?> 
<response> 
    <result>0</result> 
    <message>Success.</message> 
    <function>test</function> 
    <data> 
    <GET/> 
    <POST/> 
    <foo> 
     <bar> 
     <bad> 
      <wolf> 
      <some_value>testtesttest</some_value> 
      </wolf> 
     </bad> 
     </bar> 
    </foo> 
    </data> 
</response> 

回答

1

你必须把下面的代码片段在开始为您的foreach循环

foreach ($data as $key => $value) 
{  
    if(array_key_exists($key, $data) && empty($value)) 
    { 
     $node->addChild($key, ""); 
    } 
    //your other code goes here 
} 

上面的代码会输出您想要的输出,如下所示。

<?xml version="1.0" encoding="UTF-8"?> 
<response> 
    <result> 
    </result> 
    <message>Success.</message> 
    <function>test</function> 
    <data> 
     <GET> 
     </GET> 
     <POST> 
     </POST> 
     <foo> 
      <bar> 
       <bad> 
        <wolf> 
         <some_value>test test test</some_value> 
        </wolf> 
       </bad> 
      </bar> 
     </foo> 
    </data> 
</response> 

我已将您的代码作为示例并通过创建类来执行它。所以这也应该为你工作。

+0

这几乎和预期的一样。我接受并改变了它,使它位于if块的else {}部分: else else if(!array_key_exists($ key,$ data)) $ node-> addChild($ key,'' ); else $ node-> addChild($ key,htmlentities($ value)); } 这工作,因为我需要它。谢谢! – 2013-05-11 20:44:47

+0

请注意,我还添加了 if(array_key_exists($ key,$ data)&& is_array($ value)&& count($ value)== 0) $ node-> addChild($ key); 到第一个foreach()循环的开始。 – 2013-05-11 21:14:45

相关问题