SimpleXML удаляет несколько узлов по индексу - PullRequest
0 голосов
/ 09 мая 2018

Я хочу удалить определенные индексы из XML-файла и сохранить его обратно.

<channel>
  <item>foo</item>
  <item>bar</item>
  <item>baz</item>
  <item>foo</item>
  ...
  <item>foo</item>
  <item>bar</item>
  <item>baz</item>
  <item>foo</item>
</channel>

У меня есть массив индексов

$indexes_to_remove = array(3,12,17);

Я загружаю файл и зацикливаюсь на индексах и пытаюсь сбросить

$xml = simplexml_load_file('content.xml');

foreach($indexes_to_remove as $id){
    unset($xml->channel->item[(int)$id][0]);
}
file_put_contents('content.xml', $xml->asXML());

Но это не работает, как ожидалось. Предметы удаляются, но не нужные (не все). Я полагаю, что это потому, что при сбрасывании простой xml-индекс испортился.

Я просмотрел существующие вопросы и попробовал

foreach($indexes_to_remove as $id){
    $result = $xml->xpath( "(//item)[$id]" );
    foreach ( $result as $node ) {
        $dom = dom_import_simplexml($node);
        $dom->parentNode->removeChild($dom);
    }
}
file_put_contents('content.xml', $xml->asXML());

Тот же результат. Я не могу понять, что я делаю неправильно.

1 Ответ

0 голосов
/ 09 мая 2018

попробуй так,

content.xml

<channel>
  <item>foo</item>
  <item>bar</item>
  <item>3rd value</item>
  <item>foo</item>

  <item>foo</item>
  <item>bar</item>
  <item>baz</item>
  <item>foo</item>

  <item>foo</item>
  <item>bar</item>
  <item>baz</item>
  <item>12th value</item>

  <item>foo</item>
  <item>bar</item>
  <item>baz</item>
  <item>foo</item>

  <item>17th value</item>
  <item>bar</item>
  <item>baz</item>
  <item>foo</item>
</channel>

PHP

$indexes_to_remove = array(3,12,17);
$xml = simplexml_load_file('content.xml', 'SimpleXMLElement');
if($xml->item){
    $rindex = 0;
    foreach($indexes_to_remove as $index){   
        $index += $rindex; // changing index after removed the node
        $dom = $xml->xpath('/channel/item['.$index.']');
        $dom = dom_import_simplexml($dom[0]);   
        $dom->parentNode->removeChild($dom);
        $rindex--;               
    }
}
file_put_contents('content.xml', $xml->asXML());

выход

<channel>
  <item>foo</item>
  <item>bar</item>
  <item>foo</item>

  <item>foo</item>
  <item>bar</item>
  <item>baz</item>
  <item>foo</item>

  <item>foo</item>
  <item>bar</item>
  <item>baz</item>

  <item>foo</item>
  <item>bar</item>
  <item>baz</item>
  <item>foo</item>

  <item>bar</item>
  <item>baz</item>
  <item>foo</item>
</channel>
...