PHP SimpleXML: удалять элементы с

Я просто могу удалить элемент из элемента simpleXML с помощью:

unset($this->simpleXML->channel->item[0]); 

но я не могу с a для:

  $items = $this->simpleXML->xpath('/rss/channel/item'); for($i = count($items); $i > $itemsNumber; $i--) { unset($items[$i - 1]); } 

некоторые элементы удаляются из $ items (Netbeans Debug может подтвердить это), но когда я снова получаю путь (/ rss / channel / item), ничего не было удалено.

Что не так?

SimpleXML не обрабатывает удаление узлов, для этого вам нужно использовать DOMNode. К счастью, при импорте узлов в DOMNode экземпляры указывают на одно и то же дерево.

Итак, вы можете это сделать:

 <?php $items = $this->simpleXML->xpath('/rss/channel/item'); foreach ($items as $item) { $node = dom_import_simplexml($item); $node->parentNode->removeChild($node); } 

В настоящее время вы, как вы знаете, только отключили элемент из массива.

Чтобы заставить магическое расцепление работать с SimpleXMLElement, вам нужно либо сделать, как предложил Ксавье Барбоса, или дать PHP немного подтолкнуть, чтобы отбросить правильное поведение, не срабатывающее.

Единственное изменение в нижеприведенном фрагменте кода – это добавления [0] . Тяжелый акцент на слово волшебное .

 $items = $this->simpleXML->xpath('/rss/channel/item'); for($i = count($items); $i > $itemsNumber; $i--) { unset($items[$i - 1][0]); } 

С учетом сказанного я бы рекомендовал (как Ксавье и Джош) перебраться в DOM-землю для манипулирования документом.

Ну, я пытался разузнать, как удалить последнего ребенка из XML-документа. Затем я вставляю новый элемент вверху. Таким образом всегда есть определенное количество элементов в моей ленте rss. Я не мог заставить работу xpath работать. Это может быть из-за свободного сервера, который я использую, но в любом случае. Это то, что я сделал. Мой XML-документ – это rss-канал, поэтому у меня есть 6 элементов, прежде чем элементы начнутся. то есть. название, описание под каналом. $ file = 'newrss.xml'; // получить файл

 $fp = fopen($file, "rb") or die("cannot open file");//open the file $str = fread($fp, filesize($file));//read the file $xml = new DOMDocument();//new xml DOMDocument $xml->formatOutput = true; $xml->preserveWhiteSpace = false; $xml->loadXML($str) or die("Error");//Load Document // get document element $root = $xml->documentElement; $fnode = $root->firstChild; $ori = $fnode->childNodes->item(6);//The 6th item starts the item nodes //Get the number of items in my xml. $nodeLength = $fnode->getElementsByTagName('item')->length;//count nodes $itemNum=$nodeLength+5;//I added 5 so it starts from the first item $lNode = $fnode->childNodes->item($itemNum);//Get the last child node $fnode->removeChild($lNode);//finally remove that node. 

Я знаю, что это некрасиво, но это работает хорошо. Мне потребовалось много времени, чтобы понять это, поэтому я надеюсь, что это поможет кому-то еще, так как я вижу этот вопрос много. Если вас не интересует добавление нового элемента в начало rss-списка, вы можете пропустить переменную $ ori. Кроме того, если вы не учитываете переменную $ ori, вам придется настроить $ itemNum, чтобы удалить правильный элемент.