How to Modify Xml File Using PHP

How to modify xml file using PHP

You can use the DOMDocument from PHP.

You load your file and than loop trough the childNodes of the document.

<?php
$dom=new DOMDocument();
$dom->load("file.xml");

$root=$dom->documentElement; // This can differ (I am not sure, it can be only documentElement or documentElement->firstChild or only firstChild)

$nodesToDelete=array();

$markers=$root->getElementsByTagName('marker');

// Loop trough childNodes
foreach ($markers as $marker) {
$type=$marker->getElementsByTagName('type')->item(0)->textContent;
$title=$marker->getElementsByTagName('title')->item(0)->textContent;
$address=$marker->getElementsByTagName('address')->item(0)->textContent;
$latitude=$marker->getElementsByTagName('latitude')->item(0)->textContent;
$longitude=$marker->getElementsByTagName('longitude')->item(0)->textContent;

// Your filters here

// To remove the marker you just add it to a list of nodes to delete
$nodesToDelete[]=$marker;
}

// You delete the nodes
foreach ($nodesToDelete as $node) $node->parentNode->removeChild($node);

echo $dom->saveXML();
?>

You can save your output XML like this

$dom->saveXML(); // This will return the XML as a string
$dom->save('file.xml'); // This saves the XML to a file

To do this parsing in JavaScript you should use jQuery (a small, but powerful library).

You can include the library directly from Google Code Repository.

<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>

The library is cross-browser and very small. It should be cached in many cases, because some sites use it from Google Code

$(yourXMLStringOrDocument).find("marker").each(function () {
var marker=$(this);

var type=marker.find('type').text();
var title=marker.find('title').text();
var address=marker.find('address').text();
var latitude=marker.find('latitude').text();
var longitude=marker.find('longitude').text();
});

Modify XML in PHP

One way you could do this is using DOMDocument and DOMXPath and find your elements using for example an xpath expression which will find the 'TIN' elements in the sfa namespace.

/ftc:FATCA_OECD/ftc:FATCA/ftc:ReportingFI/sfa:TIN

To update the value of the first found elemement you could take the first item from the DOMNodeList which is returned by query.

$doc = new DOMDocument();
$doc->loadXML($data);
$xpath = new DOMXPath($doc);
$res = $xpath->query("/ftc:FATCA_OECD/ftc:FATCA/ftc:ReportingFI/sfa:TIN");
if ($res->length > 0) {
$res[0]->nodeValue = "test";
}
$doc->save("yourfilename.xml");

Demo

How to update xml file using PHP?

Your program shows the form firstly, then saves data secondly.
So when you click button submit, the program shows the form with previous data first and then,
saves 'new' data.

Therefore following code works well.

 <script src="http://code.jquery.com/jquery-latest.min.js"></script>
<?php
$xml = new DOMDocument('1.0', 'utf-8');
$xml->formatOutput = true;
$xml->preserveWhiteSpace = false;
$xml->load('examples.xml');

//Get item Element
$element = $xml->getElementsByTagName('person')->item(0);

//Load child elements
$name = $element->getElementsByTagName('name')->item(0);
$comment = $element->getElementsByTagName('comment')->item(0) ;

//Replace old elements with new
$element->replaceChild($name, $name);
$element->replaceChild($comment, $comment);
?>

<?php
if (isset($_POST['submit']))
{
$name->nodeValue = $_POST['namanya'];
$comment->nodeValue = $_POST['commentnya'];
htmlentities($xml->save('examples.xml'));

}

?>

<form method="POST" action=''>
name <input type="text-name" value="<?php echo $name->nodeValue ?>" name="namanya" />
comment <input type="text-comment" value="<?php echo $comment->nodeValue ?>" name="commentnya"/>
<input name="submit" type="submit" />
</form>

Edit XML file on web page and save back to XML file using PHP

To answer your XSLT questions to render HTML form:

How can I get the node value to appear inside the input text box? And how can I get the node name to appear on the left of the input text box? ... One more thing, how can I add or remove an event?

Consider adjusting XSLT to use name() and assign value with expression: {text()}. And even wrap node name inside <label> tag with styling for alignment. Even more, add a unique <input> id (for CSS/Javascript to identify) and name (for PHP to identify) using XSLT functions: name() and position(). For better management of each event, separate script into event and events templates

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/events">
<div id="edit_xml">
<h2>My events</h2>
<form method="post" action="#edit_xml">
<xsl:apply-templates select="event"/>
<p><input type="submit" name="submit_data" value="Submit"/></p>
</form>
</div>
</xsl:template>

<xsl:template match="event">
<xsl:for-each select="*">
<p>
<label style="display: inline-block;width: 140px;">
<xsl:value-of select="name()"/>
</label>
<input type="text" id="{concat(name(), position())}"
name="{concat(name(), position())}"
value="{text()}"/>
</p>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Online Demo

HTML Output

To remove an element, run bracketed [] condition in <xsl:apply-templates> in top layer events template:

<!-- SELECT ONLY FIRST event TO BE APPLIED -->
<xsl:apply-templates select="event[1]"/>

<!-- SELECT ONLY SECOND event TO BE APPLIED -->
<xsl:apply-templates select="event[2]"/>

<!-- SELECT ALL NODES AFTER FIRST event -->
<xsl:apply-templates select="event[position() > 1]"/>

<!-- SELECT ALL NODES BUT EXCLUDE SECOND NODE -->
<xsl:apply-templates select="event[position() != 2]"/>

<!-- SELECT ONLY LAST event TO BE APPLIED -->
<xsl:apply-templates select="event[last()]"/>

For this non-XSLT question:

The next problem is that once this has been edited then how can I get it stored back in the XML file with exactly the same structure?

You need to handle the form submission with application layer like in PHP to receive input values and bind into XML document. In fact, you can set up another XSLT solution with exact original layout to receive parameters from PHP!

Updating XML node with PHP

You're not accessing the right node. In your example, $xml holds the root node <info/>. Here's a great tip: always name the variable that holds your XML document after its root node, it will prevent such confusion.

Also, as Ward Muylaert pointed out, you need to save the file.

Here's the corrected example:

// load the document
// the root node is <info/> so we load it into $info
$info = simplexml_load_file('test.xml');

// update
$info->user->name->nameCoordinate->xName = $xPostName;
$info->user->name->nameCoordinate->yName = $yPostName;

// save the updated document
$info->asXML('test.xml');


Related Topics



Leave a reply



Submit