2013-04-30 37 views
0

我使用SimpleXML分析了XML並想截斷它。這是方法:未設置的子節點使方法消失

public function truncate(SimpleXMLElement $xml) 
{ 
    foreach ($xml->children() as $key => $value) 
    { 
     if (!empty($key) && isset($xml->$key)) 
     { 
      echo "unset $key"; 
      unset($xml->$key); 
     } 
    } 

    echo $xml->asXML(); 
    exit; 
} 

第一未設置後,它拋出這個:

警告:拍拍\持久性\文件\文本\ XML ::截斷():節點不再存在拍拍/持久性/文件/文本/ XML.php在線36

嗯,我不想解除方法。

+0

嘗試取消設置($ key); – Reshil 2013-04-30 06:54:45

+0

如果您試圖刪除一些孩子以僅獲得您想要的孩子,那麼您應該爲這些孩子使用中介陣列。 – machineaddict 2013-04-30 07:22:20

回答

0

你是的foreach-ING的孩子,但是從父刪除,如果要刪除空兒 嘗試這樣的事:

foreach ($xml->children() as $child) 
{ 
    if (empty($child)) { 
     unset($child[0]); 
    } 
} 
echo $xml->asXML(); 
2

錯誤消息「節點不再存在」 SimpleXML中意味着您正在嘗試刪除不再存在的節點。

正如您已經注意到的,這在第一次迭代未設置時不會發生,但在以下迭代中。如果你現在想象SimpleXMLElement::children()返回與兒童爲重點,並作爲值的子元素節點的從零開始的索引數組,請考慮以下更好地瞭解:

你有兩個孩子一個元素。因此children()函數返回一個有兩個數組的數組。

$children  = [ 0 => <child1>, 1 => <child2> ] 
        ^ unset($xml->{0}); 
         `-----------------^ 

$xml->children() = [ 0 => <child1>, 1 => <child2> ] 

現在刪除的第一個子元素,索引0

而第二個孩子仍然存在:

$xml->children() = [ 0 => <child2> ] 

但是,因爲你通過他們的人數訪問的孩子,和第一孩子已被移除,第二個孩子得到一個新的指標:從以前1 0現在不管你取消設置的孩子在索引1:

$children  = [ 0 => <child1>, 1 => <child2> ] 
            ^ unset($xml->{1}); 
            `-----------------^ 

$xml->children() = [ 0 => <child2> ] 

不存在任何再:

節點不再存在

看到錯誤消息?那麼如何解決呢? SimpleXML中的一個常用方法是使用一個simplexml self-reference由hakre在這個問題概述:

unset($value[0]); 

正如你所看到的,它不需要使用任何鍵。另一種選擇是,你反向兒童數組,並從結束,而不是開始。這樣,你不拉指標在你的腳下:

$children = array_reverse($xml->children()); 

foreach ($children as $key => $value) { 
    ... 
     unset($xml->$key); 
    } 
} 

但自基準可能更易於使用,因爲它也可以在你想SimpleXML中未設置一些其他情況,所以它的值得你拿well-explained read over there

一覽完整的例子:

public function truncate() 
{ 
    $xml = $this->_xml; 

    $children = $xml->children(); 
    foreach ($children as $index => $child) 
    { 
     if ($index) { 
      unset($child[0]); 
     } 
    } 

    $xml->asXML('php://output'); 
    exit; 
} 

我還要說,exit不屬於成的方法,但我把它放在這樣可以更好的取向。相反,該方法應該只是輸出截斷的XML,而不關心結束腳本。將它移出並放在調用該方法之後,因爲這是兩種不同的任務:一個是XML處理和輸出,另一個是程序流。