18

I want to modify my xml file in PHP based on the following criteria.

my xml structure look like this:

<?xml version="1.0" encoding="ISO-8859-1" ?> 

<markers>
   <marker>
      <type></type>
      <title></title>
      <address></address>
      <latitude></latitude>
      <longitude></longitude>
   <marker>
   <marker>
      <type></type>
      <title></title>
      <address></address>
      <latitude></latitude>
      <longitude></longitude>
   <marker>
</markers>

Now every time when xml going to modify, with the type attribute.

means, on first time search string == "hotels" then data related to hotels will be stored in xml file as above format.

Now when again search for hotels is done then it will remove the elements which have child element with value hotels.

and search for different query for e.g. schools is done at that time data related to the schools are appended to the xml file. with the data of the hotels.

now again search for schools is done then it will remove the element related to schools.

Thanks in advance.

Avinash
  • 585
  • 3
  • 9
  • 17

3 Answers3

37

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();
});
Cristian Toma
  • 5,662
  • 2
  • 36
  • 43
  • You add all $marker's from within the foreach to the $nodesToDelete array. – Cristian Toma Jul 28 '09 at 13:46
  • Yes i have done but not working $root=$dom->documentElement->firstChild For this line i have used all option given by you but no one is working. pl send me proper format for all three option. – Avinash Jul 28 '09 at 14:00
  • I changed the code, this should work now. $root wasn't the problem but the firstChild in it was of DOMText type and we wanted only the DOMElements with the tag 'marker'. If you have any other problems I am open to discussion. – Cristian Toma Jul 28 '09 at 14:20
  • Thanks Christian, $root=$dom->documentElement; is works for me, thanks a lot – Avinash Jul 29 '09 at 04:39
  • hi Christian i have bit of problem with reading the xml file in javascript. My xml file format is as above. Please suggest me the right way. i need that its loop through all marker element and give the value of each child element... thanks – Avinash Jul 29 '09 at 09:46
  • Sorry for my late answer. I will edit my answer with the right way to do this in JavaScript. The best way to do this in JavaScript is by using a library (like jQuery). – Cristian Toma Jul 29 '09 at 10:40
  • hi Christian, I have bit of confusion for creating xml file, i have to create separate xml file for each user which are using my web page. how can i do this. is there any option to create xml file on the user's machine? It will be easy to map the file in all javascript function.. – Avinash Jul 29 '09 at 12:49
  • When you create it in JavaScript it creates it on the users machine. If you create it in PHP you can use sessions to check if this is a known user or a new one. – Cristian Toma Jul 29 '09 at 14:55
7

Document Object Model (DOM) is the answer.

<?
 $dom=new DomDocument();
 $dom->Load("file.xml");
 $root=$dom->documentElement;
 ...
 $dom->Save("file.xml");
?>
KV Prajapati
  • 93,659
  • 19
  • 148
  • 186
  • but how could i loop through the xml file elments..? – Avinash Jul 28 '09 at 11:52
  • 31
    The purpose of StackOverflow, in my opinion, is to help users by giving them examples that may help them in resolving their issue. Not to imply that they haven't read or searched in the documentation. – Cristian Toma Jul 29 '09 at 17:56
1
<?php
$xml = new DOMDocument('1.0','UTF-8');
$xml->preserveWhiteSpace = FALSE;
            
$xml->load("markers.xml");
        
$mar = $xml->getElementsByTagName("marker");
foreach($mar as $row){


            $type = $row->getElementsByTagName('type')->item(0);
            $title = $row->getElementsByTagName('title')->item(0);
            $address = $row->getElementsByTagName('address')->item(0);
            $latitude = $row->getElementsByTagName('latitude')->item(0);
            $longitude = $row->getElementsByTagName('longitude')->item(0);
            
            $row->replaceChild($type, $type);
            $row->replaceChild($title, $title);
            $row->replaceChild($address, $address);
            $row->replaceChild($latitude, $latitude);
            $row->replaceChild($longitude, $longitude);
          
            ?>
            
<form id="q_form" method="post" action="">
    <div class="form-group form-group-lg">
        <div class="table-responsive">
            <table id="choices_table"  class="table table-bordered"  >
                <tr>
                    <td>
                        <div class="form-group">
                            <input type="type"
                                    name ="title" 
                                    value="<?php echo $type->nodeValue ?>"
                                    />
                        </div>
                    </td>
                    <td>
                    <div class="form-group">
                        <input type="text"
                                name ="title" 
                                value="<?php echo $title->nodeValue ?>"
                                />
                     </div>
                    </td>
                    <td>
                    <div class="form-group">
                        <input type="text"
                                name ="address" 
                                value="<?php echo $address->nodeValue ?>"
                                />
                     </div>
                    </td>
                    <td>
                    <div class="form-group">
                        <input type="latitude"
                                name ="latitude" 
                                value="<?php echo $latitude->nodeValue ?>"
                                />
                     </div>
                    </td>
                    <td>
                    <div class="form-group">
                        <input type="latitude"
                                name ="longitude" 
                                value="<?php echo $longitude->nodeValue ?>"
                                />
                     </div>
                    </td>
        </table>
        </div>  
    
</div>
    <input type="submit"  name="submit" value=" EDIT "  class="btn btn-primary" />
</form>  
    <?php



    if (isset($_POST['submit']))
    {
    $type->nodeValue = $_POST['type'];    
    $text->nodeValue = $_POST['text'];
    $address->nodeValue = $_POST['address'];
    $latitude->nodeValue = $_POST['latitude'];
    $longitude->nodeValue = $_POST['longitude'];
    $xml->save("markers.xml");
        }
    
}

?>
Nour Hoda
  • 11
  • 3