Solved

removing xml elements and children

Posted on 2014-04-07
5
525 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
  • 2
  • 2
5 Comments
 

Author Comment

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

Accepted Solution

by:
Rob Jurd, EE MVE earned 500 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 42

Expert Comment

by:Rob Jurd, EE MVE
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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Preface This is the third article about the EE Collaborative Login Project. A Better Website Login System (http://www.experts-exchange.com/A_2902.html) introduces the Login System and shows how to implement a login page. The EE Collaborative Logi…
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
The purpose of this video is to demonstrate how to prevent comment spam on a WordPress Website. This will be demonstrated using a Windows 8 PC. Plugin Akismet will be used. Go to your WordPress login page. This will look like the following: myw…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

708 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now