2013-05-09 34 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

相關問題