PHP SimpleXML: Supprimer des éléments avec for

je peux simplement supprimer un élément d'un élément simpleXML avec:

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

mais je ne peux pas avec le A pour:

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

certains éléments sont supprimés de $items (Netbeans Debug peut confirmer cela) mais quand je reçois le chemin à nouveau (/rss/channel/item) rien n'a été supprimé.

Qu'est-ce qui ne va pas?

4
demandé sur Xavier Barbosa 2011-01-19 04:05:02

3 réponses

SimpleXML ne gère pas la suppression de noeud, vous devez utiliser DOMNode pour cela. Heureusement, lorsque vous importez vos noeuds dans DOMNode, les instances pointent vers le même arbre.

Donc, vous pouvez le faire :

<?php

$items = $this->simpleXML->xpath('/rss/channel/item');
foreach ($items as $item) {
    $node = dom_import_simplexml($item);
    $node->parentNode->removeChild($node);
}
6
répondu Xavier Barbosa 2011-01-19 08:49:48

vous êtes actuellement seulement, comme vous le savez, unsetting l'élément du tableau.

pour obtenir le magique unsetting pour travailler sur le SimpleXMLElement, vous devez soit faire comme Xavier Barbosa suggéré ou donner à PHP un petit coup de pouce à tirer sur le comportement correct unsetting.

Le seul changement dans l'extrait de code ci-dessous est l'ajout de [0] . Lourd l'accent sur le mot magique .

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

cela dit, je recommanderais (comme Xavier et Josh l'ont fait) de déménager dans le DOM-land pour manipuler le document.

2
répondu salathe 2017-05-23 10:29:47

Eh bien, je me creusais le cerveau en essayant de trouver comment supprimer le dernier enfant d'un document xml. Puis j'insère un nouvel élément en haut. De cette façon, il ya toujours une quantité d'articles dans mon flux rss. Je n'ai pas pu faire marcher le truc de xpath. Cela pourrait être à cause du serveur libre que j'utilise mais de toute façon. C'est ce que j'ai fait. Mon document xml est un flux rss, donc j'ai 6 éléments avant que les éléments ne commencent. IE. le titre,la description sous la manche. $fichier = 'newrss.xml';//obtenir le fichier

$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.

je sais que ce n'est pas joli mais il fonctionne bien. Il m'a fallu une éternité pour comprendre cela, alors j'espère que cela aidera quelqu'un d'autre puisque je vois cette question beaucoup. Si vous n'êtes pas intéressé à ajouter votre nouvel élément en haut de la liste rss, alors vous pouvez sauter la variable $ori. De plus, si vous omettez la variable $ori, vous devrez ajuster $itemNum afin de supprimer l'élément correct.

0
répondu jaybyrd 2015-08-07 12:29:31