PHP SimpleXML: удаление элементов с помощью for - PullRequest
4 голосов
/ 19 января 2011

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

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

, но я не могу с помощью a for:

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

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

Что не так?

Ответы [ 3 ]

6 голосов
/ 19 января 2011

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

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

2 голосов
/ 28 января 2011

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

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

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

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

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

0 голосов
/ 07 августа 2015

Ну, я ломал голову, пытаясь понять, как удалить последнего ребенка из 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, чтобы удалить правильный элемент.

...