Jakub Folejtar
Jakub Folejtar

Reputation: 340

Append child to xml based on attribute of the parent node in php

I would like to ask, how to easily append new node to the end of found node in php. Lets say I have xml like this:

<Root>
    <child id=1>
        <text>smth</text>
    </child>
</Root>

I want to find the child element with id 1 and then append another node as last. I was trying to find an answer, but it either answer how to find it, or how to write into it, unfortunately I was not able to put it together.

I would be really happy if someone can help me with this.

Upvotes: 0

Views: 1255

Answers (2)

ThW
ThW

Reputation: 19482

In DOM, you use Xpath to find nodes, DOMDocument::create*() to create the nodes and methods like DOMNode::appendChild() to put them into the document.

$xml =<<< END
<Root>
    <child id="1">
        <text>smth</text>
    </child>
</Root>
END;

$document = new DOMDocument("1.0");
$document->preserveWhiteSpace = false;
$document->formatOutput = true;
$document->loadXml($xml);
$xpath = new DOMXpath($document);

foreach ($xpath->evaluate('//*[@id="1"][1]') as $parentNode) {
  $parentNode
    ->appendChild($document->createElement('text'))
    ->appendChild($document->createTextNode('node value'));
}

echo $document->saveXML();

Output:

<?xml version="1.0"?>
<Root>
  <child id="1">
    <text>smth</text>
    <text>node value</text>
  </child>
</Root>

For huge XML files you can use XMLReader/XMLWriter, but you can not modify the document. You will have to read the original step by step and write a modified copy.

Upvotes: 0

Dekel
Dekel

Reputation: 62536

You can use the xpath to find the relevant node (based on the id) and then use the addChild to add new child-node to the node you just found:

$str =<<< END
<Root>
    <child id="1">
        <text>smth</text>
    </child>
</Root>
END;

$result = simplexml_load_string($str);

$child = $result->xpath("*[@id='1']")[0];
$child->addChild('text', 'node value');

// The part from here is only to make the output pretty-xml
// instead you can just use $result->saveXML()
$dom = new DOMDocument("1.0");
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($result->saveXML());
var_dump($dom->saveXML());

The output will be:

string(115) "<?xml version="1.0"?>
<Root>
    <child id="1">
        <text>smth</text>
        <text>node value</text>
    </child>
</Root>
"

Upvotes: 1

Related Questions