PHP Xml Inserting Element After (Or Before) Another Element

PHP XML inserting element after (or before) another element

You might try this; I didn't test it, but the solution comes from using insertBefore instead of appendChild.

$shop = $dom->getElementsByTagName("shop")->item(0);
$section = $dom->documentElement->insertBefore($dom->createElement('section'),$shop);

using PHP to edit xml - insert after last

I'm not sure if I'm missing what you mean, but it worked as expected for me?

Looking at the docs "The reference node. If not supplied, newnode is appended to the children."

So, although it was appending for me anyway, maybe just omit the second parameter?

$root->insertBefore( $placemark );

(Saved your xml into file.xml)

$xmldoc = new DOMDocument();
$xmldoc->load("file.xml");

// find the Folder tag
$root = $xmldoc->getElementsByTagName('Folder')->item(0);

// create the <placemark> tag
$placemark = $xmldoc->createElement('Placemark');

// add the placemark tag After the last element in the <Folder> tag
$root->insertBefore( $placemark );

$xmldoc->save('file.xml', LIBXML_NOEMPTYTAG);

Which output the following

    <?xml version="1.0"?>
<Folder>
<Placemark>
<name><![CDATA[scscsc]]></name>
<description><![CDATA[Description:ascasc<c,ascascasc<br>]]></description>
<styleUrl>#placemark-brown</styleUrl>
<ExtendedData>
</ExtendedData>
<Point>
<coordinates>24.069631625000056,-23.784080251008078,0</coordinates>
</Point>
</Placemark>
<Placemark></Placemark>
</Folder>

php/simplexml adding elements before and after text

From the viewpoint of DOM (and SimpleXML is an abstraction on top of that), you're do not insert elements around text. You replace a text nodes with a mix of text nodes and element nodes. SimpleXML has some problems with mixed child nodes, so you might want to use DOM directly. Here is a commented example:

$xml = <<<'XML'
<record>
<letter>
<header>To Alice from Bob</header>
<body>Hi, how is it going?</body>
</letter>
</record>
XML;

// the words and the tags you would like to create
$words = ['Alice' => 'to', 'Bob' => 'from'];
// a split pattern, you could built this from the array
$pattern = '((Alice|Bob))';

// bootstrap the DOM
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);

// iterate any text node with content
foreach ($xpath->evaluate('//text()[normalize-space() != ""]') as $text) {
// use the pattern to split the text into an list
$parts = preg_split($pattern, $text->textContent, -1, PREG_SPLIT_DELIM_CAPTURE);
// if it was split actually
if (count($parts) > 1) {
/// iterate the text parts
foreach ($parts as $part) {
// if it is a word from the list
if (isset($words[$part])) {
// add the new element node
$wrap = $text->parentNode->insertBefore(
$document->createElement($words[$part]),
$text
);
// and add the text as a child node to it
$wrap->appendChild($document->createTextNode($part));
} else {
// otherwise add the text as a new text node
$text->parentNode->insertBefore(
$document->createTextNode($part),
$text
);
}
}
// remove the original text node
$text->parentNode->removeChild($text);
}
}

echo $document->saveXml();

Output:

<?xml version="1.0"?>
<record>
<letter>
<header>To <to>Alice</to> from <from>Bob</from></header>
<body>Hi, how is it going?</body>
</letter>
</record>

Insert XML structure as a child of another XML Element using PHP

You can't with SimpleXML, but if you really need manipulate your DOM or create it from scratch consider DOMDocument.

$xmlObject   = new \DOMDocument();
$xml = $xmlObject->createElement('root');
$xml_a = $xmlObject->createElement('parent');
$xml_b = $xmlObject->createElement('child');
$xml_b->setAttribute('attribute','value');
$xml_b->appendChild(new \DOMElement('item', 'itemValue'));
$xml_a->appendChild($xml_b);
$xml->appendChild($xml_a);
$xmlObject->appendChild($xml);
echo $xmlObject->saveXML();

How to insert new element after specific element in html using php?

You need to use DOMDocument class to parsing string to html. After parsing html, select third p element and use DOMNode::insertBefore to insert new element after it.

$doc = new DOMDocument();
$doc->loadHTML($html);
// find 3th p tag
$p = $doc->getElementsByTagName("p")->item(2);
// create new div tag
$div = $doc->createElement("div", "Something different");
// insert created element after 3th p
$p->parentNode->insertBefore($div, $p);
$html = $doc->saveHTML();

PHP XML - Inserting a XML node at a specific location

Well, there's no easy way that I can see with SimpleXML (it's supposed to be simple after all).

One way, would be to move the myvalues node over to DOMDocument, add the node there, then replace it with the dom node. Given that $myvalues is your <myvalues> node in SimpleXML:

$domMyValues = dom_import_simplexml($myvalues);
$newNode = $domMyValues->ownerDocument->createElement('mynewelement');
//Apply attributes and whatever to $newNode

//find the node that you want to insert it before (from the $domMyValues class
$nodes = $domMyValues->getElementsByTagName('image');
$refNode = null;
foreach ($nodes as $node) {
if ($node->getAttribute('name') == 'img02') {
$refNode = $node;
}
}
$domMyValues->insertBefore($newNode, $refNode);

Note, there's no need to convert back to SimpleXML, since any changes to the DOMElement will be applied automatically to the SimpleXML version... It will automatically append the new child if it can't find the $refNode (because it doesn't exist, etc)...

EDIT: Adding XPath

Replace the foreach block with this (Functionally equivalent, if I got the query right):

$xpath = new DOMXpath($domMyValues->ownerDocument);
$elements = $xpath->query('//image[@name="img02"]');
$refNode = $elements->item(0);

Since DOMNodeList::item() returns null for a non-existent offset, we don't even need to check to see if there are items in it.

Now, you may need/want to adjust the xpath query to be more/less specific. Here's a decent tutorial...

Edit 2

I forgot that xpath needed an @ character to tell it to check an attribute.

Here's my working code (since I don't know your exact schema):

$x = '<?xml version="1.0" ?>
<myvalues>
<images>
<image name="01">Foo</image>
<image name="02">Bar</image>
</images>
</myvalues>';

$dom = new DomDocument();
$dom->loadXML($x);
$xpath = new DOMXpath($dom);

$elements = $xpath->query('//images/image[@name="01"]');
$elements = $xpath->query('//image[@name="01"]');
$elements = $xpath->query('/myvalues/images/image[@name="01"]');

append xml nodes inside another node in php

This is my solution:

if($xmlData->body){
$xmlIterator = new SimpleXMLIterator($xmlData->body->asXML());
$xmlIterator->rewind();
$txtBody = "";

for($i=0; $i < ($xmlIterator->count()); $i++){
$txtBody .= (trim($xmlIterator->current()) <> '') ? "<p>".trim($xmlIterator->current())."</p>" : "";
$xmlIterator->next();
}
#INSERT PULLQUOTE
foreach($xmlData->pullquote as $pull){
$txtBody .= $pull;

foreach ($pull->children() as $child){
$txtBody .= $child;
}

}

$data = $txtBody;
}

how to insert a child note right before the first element of an XML?

<?php
$rssDoc = new DOMDocument();
$rss_file = 'C:\test.xml';
$rssDoc->load($rss_file);
$items = $rssDoc->getElementsByTagName('source');

$firstItem = $items->item(0);

$newItem[] = $rssDoc->createElement('lastBuildDate', 'Fri, 10 Dec 2008 22:49:39 GMT');
$newItem[] = $rssDoc->createElement('publisherurl', 'http://www.xyz.com');
$newItem[] = $rssDoc->createElement('publisher', 'XYZ');
foreach ($newItem as $xmlItem){
$firstItem->insertBefore($xmlItem,$firstItem->firstChild);
}

echo $rssDoc->save('C:\test.xml');
?>

Hey, Manoj Kumar, this should work for you. try this. :)

both appendChild and insertBefore when called on DOMDocument append node after root

This seems to work:

Initial XML file -

<!-- test.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<root>
<node Id="1">
<Clicks>click1</Clicks>
</node>
</root>

PHP -

<?php

function addUser($tag, $hash) {
$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->load('test.xml');

$parent = $dom->createElement($tag);
$dom->documentElement->appendChild($parent);
foreach($hash as $elm => $value){
$n = $dom->createElement($elm);
$n->appendChild( $dom->createTextNode( $value ) );
$parent->appendChild($n);
}

$dom->save('test.xml');
}

$arr = array( 'name' => 'pushpesh', 'age' => 30, 'profession' => 'SO bugger' );
addUser('user', $arr);

XML file is now -

<!-- test.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<root>
<node Id="1">
<Clicks>click1</Clicks>
</node>
<user>
<name>pushpesh</name>
<age>30</age>
<profession>SO bugger</profession>
</user>
</root>

Hope this helps.

insertBefore xml php

Methods like insertBefore() and appendChild() have to be called on the parent node. The document itself is a node, too. So it has the methods and allows to add multiple nodes, but only a single element node.

In your case, here are to possible approaches.

Use the DOMNode::parentNode property

$nodo_zero = $doc->getElementsByTagName('image')->item(0);
$nodo_zero->parentNode->insertBefore($nuevo_nodo,$nodo_zero);

Or fetch the juiceboxgallery node and use the DOMNode::firstChild property.

$gallery = $doc->getElementsByTagName('juiceboxgallery')->item(0);
$gallery->insertBefore($nuevo_nodo, $gallery->firstChild);


Related Topics



Leave a reply



Submit