Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

removing xml elements and children

Posted on 2014-04-07
5
Medium Priority
?
584 Views
Last Modified: 2014-04-10
I've been working on this project that gives my HR Department the ability to upload and edit job postings on our company's website by using xml to xsl to HTML (where the xml info can be edited) then back to xsl to xml (with new xml value changes in place). The uploader works, the HTML form generates the xml values correctly, and the edit feature works as well. The only problem I have is deleting elements from the xml. I tried to build a form with radio buttons that would make it easy for a "non-coder" to delete a job opportunity by just checking the radio button and clicking a submit button. So far the code I've tried to use does not delete any of the xml elements.

Here's an example of the xml I use:
<?xml version="1.0"?>
-<EMPLOYMENT_OPPORTUNITIES>
    -<OPPORTUNITY id="0">
          <INDEXABLE>0</INDEXABLE>
          <POSITION>CCR</POSITION>
          <DATELINE>05/15/2010</DATELINE>
          <LOCATION>files/CustomerCareRepresentative.pdf</LOCATION>
    </OPPORTUNITY>
   -<OPPORTUNITY id="1">
          <INDEXABLE>1</INDEXABLE>
          <POSITION>Staking Technician</POSITION>
          <DATELINE>05/15/2010</DATELINE>
          <LOCATION>files/StakingTechnician.pdf</LOCATION>
     </OPPORTUNITY>
</EMPLOYMENT_OPPORTUNITIES>

Open in new window


my php file looks like this:

(This is what creates the radio button display for each job the code loops through)
<html>
<head>
<title>Job Remover</title>
</head>
<body>
<form action="removejobs.php" method="post"  id="form1">

    <?php
     $Parent = 0;
     $Nodes = 0;
     $xmlLoad =simplexml_load_file("jobs.xml");
     foreach($xmlLoad ->children() as $x)
       {
        echo "Delete " . $x->getName() . ": " . $x->attributes() . "<br>"; 
        foreach($x ->children() as $child)
        {
			
        echo "<input type='radio' id='".$Parent."-". $child->getName() ."' name='" . $child->getName() . "' value='" . $child . "' />'". $child ."<br>";
			 
            $Nodes = $Nodes + 1;
        }
        echo "<br>";
        $Parent = $Parent + 1;
        }
     ?> 
     
        <button onclick='myFunction()' >Delete it</button>

</form>
</body>
</html>

Open in new window

The user would check each entry under each <opportunity> and then click the submit button to delete each OPPORTUNITY element (child nodes delete as well)


My removejobs.php code looks like this:

<?php

     $Nodes = 0;
     $Parent = 0;
     $xmlLoad =simplexml_load_file("jobs.xml");
	 
function myFunction()
	{
	 		
      foreach($xmlLoad ->children() as $x)
        {
            foreach($x ->children() as $child)
            { 
				  if(isset($_POST["INDEXABLE"]))
                {  
                    $child[0] = $_POST[$Parent . "-" . $child->removeChild()]; 
				}
				
                $Nodes = $Nodes + 1;
            }
            $Parent = $Parent + 1;
        }
		}
      $xmlLoad->asXML('jobs.xml');
      echo "File Updated"; 
	
?>

Open in new window



However, its not working correctly.

So my question is, how can I open the jobs.xml file, delete an <OPPORTUNITY> element and it's child nodes, and then resave jobs.xml (save as the same name)? The most important thing is that it has to be completely user friendly meaning the entire action has to be performed by the user using the jobRemover.php form

Thank you
files.zip
0
Comment
Question by:shart68
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
5 Comments
 

Author Comment

by:shart68
ID: 39988823
Thanks, I appreciate the assistance.
0
 
LVL 43

Accepted Solution

by:
Rob earned 2000 total points
ID: 39991258
Ok there was a bit I had to change:

<button> has to have type='submit'.  you had onclick="myFunction()" but the button expects that to be a javascript function, not a php one.  In otherwords you can't call php functions directly from javascript / html
Changed the <input> types to be checkboxes for more than one delete at a time
Changed the <input> name to essentially be an array of elements to delete.  Anything checked is put in this array
Changed the <input> values to be the parent index and the child name as this is the value that is passed in the array

index.php
<html>
<head>
<title>Job Remover</title>
</head>
<body>
<form action="removejobs.php" method="post"  id="form1">

    <?php
     $Parent = 0;
     $Nodes = 0;
     $xmlLoad = simplexml_load_file("jobs.xml");

     foreach($xmlLoad->children() as $x)
       {
        echo "Delete " . $x->getName() . ": " . $x->attributes() . "<br>";
        foreach($x->children() as $child)
        {

        echo "
        	<input
        		type='checkbox'
        		name='nodes[]'
        		value='".$Parent."-". $child->getName() ."'
        	/>'". $child ."<br>";

            $Nodes = $Nodes + 1;
        }
        echo "<br>";
        $Parent = $Parent + 1;
        }
     ?>
        <button type='submit'>Delete it</button>

</form>
</body>
</html>

Open in new window


In the removejobs there was quite a bit of change:
Removed the myFunction function as it is not relevant or available to call from the client
Code changed to loop through all submitted deletions and match them to a parent and child node
Use of unset to delete the node

removejobs.php
<?php

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

$nodes = (isset($_POST["nodes"])) ? $_POST["nodes"] : array();

$opportunities = $xmlLoad->children();

foreach($nodes as $n) {
	list($p_index,$c_index)=explode("-",$n);
	$tmp=$opportunities[$p_index*1]->children();
	unset($tmp->$c_index);
}

echo "<br/>";

$xmlLoad->asXML('jobs.xml');

echo "File Updated";

?>

Open in new window


Please let me know if you need me to explain any of this further.

Rob
0
 

Author Closing Comment

by:shart68
ID: 39991404
Thank you for giving me a hand with this. For some reason, everytime I would try a search online for a solution, I would find either solutions that lead to dead ends, solutions using other languages (C#, Java, etc.) or partial resolutions. Before I go, would you mind giving me brief explanation of the three lines below (as this is my first time seeing this code).

list($p_index,$c_index)=explode("-",$n);
      $tmp=$opportunities[$p_index*1]->children();
      unset($tmp->$c_index);

Thanks again!
0
 
LVL 43

Expert Comment

by:Rob
ID: 39991482
My pleasure and that's what this site is here for; those solutions that you can't find anywhere else ;)

More than happy to explain those three lines (along with others if you want?)

list($p_index,$c_index)=explode("-",$n);
explode() just splits a string by a delimiter.  In your case we had the index of the parent separated from the child node name by using a dash, eg 0-INDEXABLE.

list() takes each element of an array and assigns it to each of the arguments you pass with the last one taking the remainding elements of the array if you pass less arguments than there are elements in the array.
eg list($var1, $var2, $var3) = array(1,2,3,4);
so that $var1 = 1, $var2 = 2, $var3 = [3,4];
In your case it meant i could assign the index of the parent to $p_index and the child node name to $c_index (maybe the variable should be called $c_name but don't worry about it!)

$tmp=$opportunities[$p_index*1]->children();
When parsed, the $p_index variable is treated as a string.  Multiplying it by 1 just converts it to an integer, which is required to index the array of OPPORTUNITY nodes.  The children of each OPPORTUNITY node are then assigned to a temporary variable $tmp

unset($tmp->$c_index);
There is no "deleteChild()" function so the way to do it is to delete the variable itself / unset it.  unset is a general php function (not specific to the simplexml class). Calling it on any variable will destroy that variable

HTH

Rob
0

Featured Post

Moving data to the cloud? Find out if you’re ready

Before moving to the cloud, it is important to carefully define your db needs, plan for the migration & understand prod. environment. This wp explains how to define what you need from a cloud provider, plan for the migration & what putting a cloud solution into practice entails.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Build an array called $myWeek which will hold the array elements Today, Yesterday and then builds up the rest of the week by the name of the day going back 1 week.   (CODE) (CODE) Then you just need to pass your date to the function. If i…
Many old projects have bad code, but the budget doesn't exist to rewrite the codebase. You can update this code to be safer by introducing contemporary input validation, sanitation, and safer database queries.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question