tags:

views:

42

answers:

2

hi every one. My xml file is named cgal.xml

<?xml version="1.0"?>
<item>
  <name><![CDATA[<img src="event_pic/pic1.jpg" />CALENDAR]]></name>
  <description title="NAM ELIT AGNA, ENDRERIT SIT AMET, TINCIDUNT AC." day="13" month="8" year="2010" id="15"><![CDATA[<img src="events/preview/13p1.jpg" /><font size="8" color="#6c6e74">In Gladiator, victorious general Maximus Decimus Meridias has been named keeper of Rome and its empire by dying emperor Marcus Aurelius, so that rule might pass from the Caesars back to the people and Senate. Marcus\' neglected and power-hungry son, Commodus, has other ideas, however. Escaping an ordered execution, Maximus hurries back to his home in Spain, too l</font>]]></description>
</item>

and my PHP function is:-

$doc = new DOMDocument;
            $doc->formatOutput = TRUE;
            $doc->preserveWhiteSpace = FALSE;

$doc->simplexml_load_file('../cgal.xml');
         foreach($doc->description as $des)
            {
                if($des['id'] == $id) {
                    $dom=dom_import_simplexml($des);
                    $dom->parentNode->removeChild($dom);
                }
            }
            $doc->save('../cgal.xml');

id is passed dynamically

I want to remove node according to id

A: 

You dont need to load or import the XML from SimpleXml. You can load it directly with DOM. Also, you can remove the node in the same way as you are doing in your question updatin xml in php. Just change the XPath Query to read

$query = sprintf('//description[@id="%s"]', $id);

or

$query = sprintf('/item/description[@id="%s"]', $id);

You can also use getElementById instead of an XPath, if your XML validates against a DTD or Schema that actually defines id as an XML ID. This is explained in Simplify PHP DOM XML parsing - how?.

Gordon
A: 

Well, first off, there's no DomDocument::simplexml_load_file() method. Either use dom document, or don't... So using DomDocument:

$doc = new DomDocument();
$doc->formatOutput = true;
$doc->preserveWhiteSpace = true;

$doc->loadXml(file_get_contents('../cgal.xml'));

$element = $doc->getElementById($id);
if ($element) {
    $element->parentNode->removeChild($element);
}

That should do it for you...

Edit:

As Gordon points out, that may not work (I tried it, it doesn't all the time)... So, you could either:

$xpath = new DomXpath($doc);
$elements = $xpath->query('//description[@id="'.$id.'"]');
foreach ($elements as $element) { 
    $element->parentNode->removeChild($element);
}

Or, using SimpleXML, you can recurse over each node (less performant, but more flexible):

$simple = simplexml_load_file('../cgal.xml', 'SimpleXmlIterator');
$it = new RecursiveIteratorIterator($simple, RecursiveIteratorIterator::SELF_FIRST);
foreach ($it as $element) {
    if (isset($element['id']) && $element['id'] == $id) {
        $node = dom_import_simplexml($element);
        $node->parentNode->removeChild($node);
    }
}
ircmaxell
This will fail unless he has a DTD or a Schema to validate against. DOM will not recognize the ID attribute as such, but treat it as a regular attribute.
Gordon
Thanks @Gordon, I've updated my answer with 2 other possibilities...
ircmaxell