Solved

removing xml elements and children

Posted on 2014-04-07
5
537 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

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

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

Suggested Solutions

This article discusses four methods for overlaying images in a container on a web page
Boost your ability to deliver ambitious and competitive web apps by choosing the right JavaScript framework to best suit your project’s needs.
The purpose of this video is to demonstrate how to set up an RSS Feed on a WordPress Website. This will be demonstrated using a Windows 8 PC. Feedburner will be used for this demonstration. Go to your WordPress login page. This will look like the…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

825 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