Mario Legenda
Mario Legenda

Reputation: 759

xml remove child node in php

I'm trying to remove the "druzenje" element by the 'id' attribute. I know that for that to happen, i have to remove all the child nodes from that element.

<?xml version="1.0" encoding="utf-8"?>
<druzenja>
    <druzenje id="1">
        <podaci attribute="some-data"/>
    </druzenje>
    <druzenje id="3">
        <podaci attribute="some-data"/>
    </druzenje>
</druzenja>

The code to remove is this...

    $druzenja = $this->dom->getElementsByTagName('druzenje');

    foreach($druzenja as $node) {
        if($node->getAttribute('id') == $id) {
            $podaciNodeList = $node->getElementsByTagName('podaci');
            foreach($podaciNodeList AS $podaciNode) {
                $node->removeChild($podaciNode);
            }

            $this->dom->documentElement->removeChild($node);
            return true;
        }
    }

I presume that removing a node by an 'id' attribute could be bad design but I based a lot of code on that and so far, there hasn't been any problems. I also have a code that removes the "podaci" element that works in a similar way and it does that with no problems, but here it fails. The code won't remove the "podaci" and "druzenje" element even though removeChild() returns the DomElement object which means its successful but it's not.

Any ideas?

Upvotes: 0

Views: 853

Answers (3)

ThW
ThW

Reputation: 19502

getElementsByTagName() returns "live" result that you remove the elements from the DOM. Copy it to an array to get a fixed list.

$druzenja = iterator_to_array(
  $this->dom->getElementsByTagName('druzenje')
);

foreach ($druzenja as $node) {
  if ($node->getAttribute('id') == $id) {
    $node->parentNode->removeChild($node);
  }
}

Xpath would allow you to use more complex conditions. The result is not live.

$xpath = new DOMXpath($this->dom);
foreach ($xpath->evaluate('//druzenje[@id="'.$id.'"]') as $node) {
  $node->parentNode->removeChild($node);
}

Upvotes: 1

Mario Legenda
Mario Legenda

Reputation: 759

Someone kill me. I haven't been saving. I apologize for wasting someone's precious time.

Upvotes: 1

Oswald
Oswald

Reputation: 31685

$element = $this->dom->getElementById($id);
$element->parentNode->removeChild($element);

Upvotes: 1

Related Questions