Elias Ranz
Elias Ranz

Reputation: 411

How do you remove a XML Element and All it's Multi-Level Children Using PHP?

I'm trying to delete a particular a specific node in a XML structure. I want to be able to delete all of the children of the Employee element that contains the specific username that I specify from a form field and all the children that relate to it. I've been using SimpleXML to load in all the data, but I can reload in the data via another method. I'm wondering what the best method to delete all the Children no matter how many levels deep the element is. All the solutions that I've come across so far have only been one level deep. I would like to delete the user with the username UserToDelete. An example of the structure is as follows.

<Employees>
  <Employee Status="Part-time">
     <First_Name>...</First_Name>
     <Last_Name>...</Last_Name>
     <Position>...</Position>
     <SSN>...</SSN>
     <Contact_Info>
         <Office_Phone>...</Office_Phone>
         <Email>...</Email>
         <Cell_Phone>...</Cell_Phone>
     </Contact_Info>
     <Access_Info level="admin">
         <Username>UserToDelete</Username>
         <Password>...</Password>
     </Access_Info>
     <Department>...</Department>
     <Date_Started>...</Date_Started>
     <Salary>...</Salary>
     <Years>5</Years>
     <Photo>...</Photo>
  </Employee>
  <Employee>  
     ....
  </Employee>
  ...
</Employees>

So to the point of the question How do I delete the entire Employee using PHP including all of the children including the elements within the contact_info and access_info. Does it matter how many levels deep the nodes are or can I do something like the following?

foreach ($xml->Employee as $employee) {
    if($username == $employee->Access_Info->Username) {
        foreach ($family as $node) {
            $node->parentNode->removeChild($node);
        }
        echo $dom->saveXML('employees.xml');
        echo "<font color='red'>".$username." deleted. </font>";
    }

}

EDIT:

I am not getting an output on the echo "<font color='red'>".$username." deleted. </font>";.

Upvotes: 0

Views: 315

Answers (1)

7stud
7stud

Reputation: 48599

So to the point of the question How do I delete the entire Employee

xml.xml:

<?xml version="1.0"?>
<Employees>

<Employee>
  <Username>Joe</Username>
  <Password>...</Password>
</Employee>


<Employee>
    <Access_Info level="admin">
      <Username>Jane</Username>
      <Password>...</Password>
    </Access_Info>
</Employee>


<Employee Status="Part-time">
     <First_Name>...</First_Name>
     <Last_Name>...</Last_Name>
     <Position>...</Position>
     <SSN>...</SSN>
     <Contact_Info>
         <Office_Phone>...</Office_Phone>
         <Email>...</Email>
         <Cell_Phone>...</Cell_Phone>
     </Contact_Info>
     <Access_Info level="admin">
       <NestedOneMoreTime>
         <Username>EmployeeToDelete</Username>
         <Password>...</Password>
       </NestedOneMoreTime>
     </Access_Info>
     <Department>...</Department>
     <Date_Started>...</Date_Started>
     <Salary>...</Salary>
     <Years>5</Years>
     <Photo>...</Photo>
</Employee>

</Employees>

php:

$xml = simplexml_load_file("xml.xml");

foreach ($xml->Employee as $employee)
{
    //Because the needed xpath feature is broken in SimpleXML, create
    //a new xml document containing only the current Employee:
    $employee_xml = simplexml_load_string($employee->asXML()); 

    //Get all Username elements in employee_xml(there
    //should only be one, which will be at position 0 in the returned array):
    $usernames_array = $employee_xml->xpath("//Username");

    if($usernames_array[0] == "UserToDelete")
    {
        unset($employee[0]); //The first element of an Element object
                             //is a reference to its DOM location
        break; //Important--you don't want to keep iterating over something
               //from which you've deleted elements.  If you need to delete
               //more than one element, save the references in an array
               //and unset() them after this loop has terminated.
    }
}

echo $xml->asXML();

Upvotes: 1

Related Questions