G'Day,

Goal: Remove an element in an xml file based on it's ID.

XML File:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE users [
<!ELEMENT firstname (#PCDATA)>
<!ELEMENT lastname (#PCDATA)>
<!ELEMENT email (#PCDATA)>
<!ELEMENT passwd (#PCDATA)>
<!ELEMENT bu (#PCDATA)>
<!ELEMENT type (#PCDATA)>
<!ELEMENT date (#PCDATA)>
<!ELEMENT accesslevel (#PCDATA)>
<!ELEMENT active (#PCDATA)>
<!ELEMENT user (firstname , lastname , email , passwd , bu , type , date , accesslevel , active)>
<!ATTLIST user id ID #REQUIRED>
<!ELEMENT users (user)+>
]>
<users>
	<user id="uid1">
		<firstname>Joe</firstname>
		<lastname>Bloggs</lastname>
		<email>jbloggs@com.com</email>
		<passwd>bloggs</passwd>
		<bu>Company</bu>
		<type>0</type>
		<date>9/11/2005</date>
		<accesslevel>0</accesslevel>
		<active>1</active>
	</user>
	<user id="uid2">
		<firstname>Foo</firstname>
		<lastname>Bar</lastname>
		<email>foo@bar.com</email>
		<passwd>foobar</passwd>
		<bu>Foo Company</bu>
		<type>0</type>
		<date>9/11/2005</date>
		<accesslevel>1</accesslevel>
		<active>1</active>
	</user>
</users>

I want to use $Dom->getElementById("uid1") (where $Dom is an instance of DOMDocument) to select that element, and thus remove that element from the document and save out $Dom to a new XML or over the original XML File.

Is this easily done, or should I rethink my strategy?

SakuraChan

    Sounds like the most straightforward way of removing a node given its ID.

      Sweet, I was hoping there wasn't some gotchyas based on not being able to remove the entire DOMElement which you're currently referencing.

      I'll post the solution later if it's in any way nice.

        if anyone is interested

        $element = $DOMDoc->documentElement;
        			$userElements = $DOMDoc->getElementsByTagName("user");
        			for ($i=0; $i < $userElements->length; $i++) {
        				if ($userElements->item($i)->getAttribute('id') == $this->userID) {
        					$index = $i;
        					break;
        				}
        			}
        			if (!isset($index)) {
        				return("User Doesn't Exist");
        			} else {
        				$user = $element->getElementsByTagName('user')->item($index);
        				$olduser = $element->removeChild($user);		
        
        			$DOMDoc->save("_data/".$this->file);
        		}

        If someone has a more graceful solution please, let me know.

        Sakurachan

          21 days later
          function deletePerson($id) {
          
          $returnVals['message'] .= "<b>Begin delete person Function</b>\r\n<ul>";
          
          // SETUP $doc
          $doc = new DomDocument;
          $doc->validateOnParse = true;
          $doc->Load('whatever.xml');
          $doc->preserveWhiteSpace = FALSE; 
          
          // VALIDATE
          	if ($doc->validate()) {
          		$returnVals['message'] .= "<li>XML CHECKS OUT\r\n";
          	}
          
          // CHECK ID
          	if ($person = $doc->getElementByID($id)) {
          		$returnVals['message'] .= "<li>Found " . $id . "\r\n";
          	} else {
          		$returnVals['message'] .= "<li>ERR:" . $id . "didn't match\r\n";
          	}
          
          //REMOVE ID
          	$user= $doc->getElementByID($id);
          	$users= $doc->documentElement;
          
          if ($oldPerson = $users->removeChild($user)) {
          	$returnVals['message'] .= "<li>Removed old $id listing<br>";
          } else {
          	$returnVals['message'] .= "Couldn't remove $id listing<br>";
          }
          $xml_string = $doc->saveXML();
          
          $returnVals['message'] .= "</ul><a href=\"self.php\">ok</a></div>\r\n";
          
          $returnVals['xml'] = $xml_string;
          
          return $returnVals;
          }
          
          $returnVals = deletePerson('moe');
          
          echo $returnVals['message'];
          // and then do whatever you want with the returned xml string.
          
          

          Here's another way of doing it where you don't need any indexing or anything. I try to build my code to be very responsive for troubleshooting so it looks kind of big, but I think the core operations are a little simpler than the above.

            Here it is without all the extra stuff

            function deletePerson($id) {
            
            // SETUP $doc
            $doc = new DomDocument;
            $doc->validateOnParse = true;  // important, so we get the id listings from the dtd
            $doc->Load('whatever.xml');
            
            //REMOVE ID
            	$user= $doc->getElementByID($id);
            	$users= $doc->documentElement;
            
            if ($oldPerson = $users->removeChild($user)) {
                // worked
                } else {
            	return "Couldn't remove $id listing";
            }
            $doc->save(whatever.xml);
            }
            
            
              a year later

              Hi,

              I have an xml file of this format.

              <?xml version="1.0" encoding="ISO-8859-1"?>
                 <contacts>
                    <entry uri="sip:vinayg@company.org">
              		<name>Vinay</name>
              		<sip> sip:vinayg@company.org </sip>
              		<Number> 9885821530 </Number>
                    </entry>
                    <entry uri="sip:vivek@company.org">
              		<name>Vivek</name>
              		<sip> sip:vivek@company.org </sip>
              		<Number> 9885821530 </Number>
                    </entry>
                 </contacts>
              

              Do note that in this XML file, the tag 'entry' is an array. Now how do I specify this in the following code.

              function deletePerson($id) {
              
              // SETUP $doc
              $doc = new DomDocument;
              $doc->validateOnParse = true;  
              $doc->Load('test.xml'); //REMOVE ID $user= $doc->getElementByID($id); $users= $doc->documentElement; if ($oldPerson = $users->removeChild($user)) { // worked } else { return "Couldn't remove $id listing"; } $doc->save('test.xml'); } deletePerson("sip:vinod@company.org");

              Kindly help urgently,

              With regards,

              tvks

                Write a Reply...