How to append to a XML file with PHP preferably with SimpleXML
With SimpleXML, you can use the addChild()
method.
$file = 'xml/config.xml';
$xml = simplexml_load_file($file);
$galleries = $xml->galleries;
$gallery = $galleries->addChild('gallery');
$gallery->addChild('name', 'a gallery');
$gallery->addChild('filepath', 'path/to/gallery');
$gallery->addChild('thumb', 'mythumb.jpg');
$xml->asXML($file);
Be aware that SimpleXML will not "format" the XML for you, however going from an unformatted SimpleXML representation to neatly indented XML is not a complicated step and is covered in lots of questions here.
Append Element to Xml file with Php
Since you are using DOMDocument, that's what you need:
$doc = new DOMDocument();
$doc->load($filename);
$firstchild = $doc->getElementsByTagName('firstchild')->item(0);
$newPage = $doc->createDocumentFragment();
$newPage->appendXML('<page name="second">
<inlude file="1.png"></inlude>
<inlude file="2.png"></inlude>
</page>');
$firstchild->appendChild($newPage);
$doc->save(filename);
trying to edit xml file using php simplexml
Second one is not possible as SimpleXMLElement
can only take a well-formed XML string or the path or URL to an XML document. But you are passing an object of class SimpleXMLElement
returned by simplexml_load_file
. That is the reason it was throwing error String couldn't be parsed to XML...
In first one the asXML()
method accepts an optional filename as parameter that will save the current structure as XML to a file.
If the filename isn't specified, this function returns a string on
success andFALSE
on error. If the parameter is specified, it
returnsTRUE
if the file was written successfully andFALSE
otherwise.
So once you have updated your XML with the hints, just save it back to file.
$settings = simplexml_load_file("settings.xml");
....
if(isset($aInformation['cName']))
{
$settings->general->communityname = $aInformation['cName'];
// Saving the whole modified XML to a new filename
$settings->asXml('updated_settings.xml');
// Save only the modified node
$settings->general->communityname->asXml('settings.xml');
}
How do I update/append data to an XML file using PHP?
Instead of creating a new XML file each time, you'll want to load your existing XML file. To reuse as much of your code as possible, use SimpleXML's file-reading function:
// This file "test.xml" is pre-populated with your base XML:
// <?xml version="1.0" encoding="UTF-8"?><entrys></entrys>
$xml = simplexml_load_file('test.xml');
We need to make a change to your schema; <entrys>
should be an array-like node of <entry>
nodes. Correct? If so, replace your current addChild
methods by creating a parent node to capture the first name, last name etc.:
$entry = $xml->addChild('entry');
$entry->addChild('fname', $fname);
$entry->addChild('lname', $lname);
$entry->addChild('location', $location);
$entry->addChild('report', $report);
$entry->addChild('description', $description);
Running this twice, we'll get something like:
<?xml version="1.0" encoding="UTF-8"?>
<entrys>
<entry>
<fname>abc</fname>
<lname>abc</lname>
<location>abc</location>
<report>abc</report>
<description>abc</description>
</entry>
<entry>
<fname>abc</fname>
<lname>abc</lname>
<location>abc</location>
<report>abc</report>
<description>abc</description>
</entry>
</entrys>
PHP SimpleXML: insert node at certain position
The following is a function to insert a new SimpleXMLElement after some other SimpleXMLElement. Since this isn't directly possible with SimpleXML, it uses some DOM classes/methods behind-the-scenes to get the job done.
function simplexml_insert_after(SimpleXMLElement $insert, SimpleXMLElement $target)
{
$target_dom = dom_import_simplexml($target);
$insert_dom = $target_dom->ownerDocument->importNode(dom_import_simplexml($insert), true);
if ($target_dom->nextSibling) {
return $target_dom->parentNode->insertBefore($insert_dom, $target_dom->nextSibling);
} else {
return $target_dom->parentNode->appendChild($insert_dom);
}
}
And an example of how it might be used (specific to your question):
$sxe = new SimpleXMLElement('<root><nodeA/><nodeA/><nodeA/><nodeC/><nodeC/><nodeC/></root>');
// New element to be inserted
$insert = new SimpleXMLElement("<nodeB/>");
// Get the last nodeA element
$target = current($sxe->xpath('//nodeA[last()]'));
// Insert the new element after the last nodeA
simplexml_insert_after($insert, $target);
// Peek at the new XML
echo $sxe->asXML();
If you want/need an explanation of how this works (the code is fairly simple but might include foreign concepts), just ask.
Extracting Data from xml file using SimpleXml
As the name of the element you want to display has a -
in it, you will need to output the element using (I cast it to a string just to be pedantic)...
echo (string)$canal->{'display-name'};
Using
$canal->display-name
will be interpreted as $canal->display
minus name
.
XML Search and addChild
This is an addition to @Geekmans answer
Your code does not look too far of. However you can greatly improve it which is why add another answer here (I would have normally edited @Geekmans answer but it's already very large).
The point of improvement is in the program flow. If the email is not found, you don't need to create a new SimpleXMLElement
, you only need to create a new <visitor>
element. Then adding the <date>
element as well as outputting the file is actually the same for both cases. This allows to remove the duplicate code:
// Specify the XML file we want to write to
$inFile = "data.xml";
// Set e-mail xml search and insert id
$search_id = 'jon.doe@aol.com';
$insert_id = preg_replace('/[^(\x20-\x7F)]*/', '', $search_id);
// Load the XML file we want to write to
$xmlFile = simplexml_load_file($inFile);
$results = $xmlFile->xpath("visitor[email='$search_id']");
// If we have a search result, email already exists in xml file
if ($results) {
$visitor = $results[0];
echo "Found Visitor: ", $visitor->email, "\n",
"First Date: ", $visitor->date, "\n";
} else {
echo "Adding new Visitor: ", $insert_id, "\n";
$visitor = $xmlFile->addChild("visitor");
$visitor->addChild("email", $insert_id);
}
echo "Adding new Date: ", $date = date('Y-m-d H:i:s'), "\n";
$visitor->addChild('date', $date);
echo "Changed XML: \n" . simplexml_pretty_print($xmlFile);
$xmlFile->asXML($inFile);
/**
* @param SimpleXMLElement $simplexml
* @link https://stackoverflow.com/a/798986/367456
*/
function simplexml_pretty_print(SimpleXMLElement $simplexml) {
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($simplexml->asXML());
return $dom->saveXML();
}
As a bonus I added the simplexml_pretty_print
function to have the output in a nicer way.
The output for jon.doe@aol.com
:
Found Visitor: jon.doe@aol.com
First Date: 2012-11-01 11:00:00
Adding new Date: 2012-11-03 10:48:05
Changed XML:
<?xml version="1.0" encoding="utf-8"?>
<visitors>
<visitor>
<email>jon.doe@aol.com</email>
<date>2012-11-01 11:00:00</date>
<date>2012-11-02 14:00:00</date>
<date>2012-11-03 10:48:05</date>
</visitor>
</visitors>
The output for info@example.com
:
Adding new Visitor: info@example.com
Adding new Date: 2012-11-03 10:52:09
Changed XML:
<?xml version="1.0" encoding="utf-8"?>
<visitors>
<visitor>
<email>jon.doe@aol.com</email>
<date>2012-11-01 11:00:00</date>
<date>2012-11-02 14:00:00</date>
</visitor>
<visitor>
<email>info@example.com</email>
<date>2012-11-03 10:52:09</date>
</visitor>
</visitors>
Tip: Whenever you spot duplicate code, there often is a way to write it in a much simpler form.
Related Topics
How to Convert All Images to Jpg
PHP - Listing All Directories and Sub-Directories Recursively in Drop Down Menu
Eloquent Many-To-Many-To-Many - How to Load Distant Relation Easily
How to Consume a Wcf Web Service That Uses Custom Username Validation with a PHP Page
Upload Images on Twitter Using PHP
Error 405 (Method Not Allowed) Laravel 5
Uncompress a Gzip File from Curl, on PHP
How to Get Array Key from Corresponding Array Value
Php: Date Larger Than Current Date
Utf-8 Special Characters Not Displaying
Can Closing the Browser Terminate the PHP Script on the Server
What's the Performance Cost of "Include" in PHP
The Requested Url /Projectname/Users Was Not Found on This Server. Laravel
How to Send Soap Xml via Curl and PHP
How Do Check If a PHP Session Is Empty