I'm working on a PHP script that allows me to delete nodes in an XML file. I would like to have a table with the different nodes displayed underneith their parent elements <tag>
. On the right of the table I want to have a delete link to delete the specific node <string>
that is adjacent to the delete link. I don't want other nodes with the same values to be effected. Only one node can be deleted at a time. I have most of the code written but when I click the delete link nothing happens (other than the URL changing). Please bare with me XML and PHP together are not my strong suit.
Here is my PHP code, it calls the filename from another file via a session. I have tested that part and it works flawlessly.
<?php
session_start();
if (isset($_SESSION['file'])) {
$fileName = $_SESSION['file'];
$symbols = simplexml_load_file ( $fileName );
if(isset($_GET['action'])){
$id = $_GET['string'];
foreach ($symbols->symbol as $symbol) {
if ($symbol['string']==$id) {
$dom = dom_import_simplexml($symbol);
$dom->parentNode->removeChild($dom);
}
echo $symbols->asXml();
}
}
echo "<table border='1'>";
foreach ($symbols->xpath(".//HighwayRoutingData") as $routingPoints){
$tag=(string)$routingPoints->tag;
echo "<tr>";
echo "<td>".$tag."</td>";
echo "<td></td>";
foreach($routingPoints->xpath(".//destinationSymbols//string") as $symbol){
$sym = (string)$symbol;
echo "<tr><td>{$sym}</td>";
echo '<td><a href="delete.php?action=delete&string='.$sym.'">Delete</a></tr>';
echo "</td>";
}
echo "</tr>";
}
echo "</table>";
}else{
echo "Session not set";
}
?>
Here is the XML files im looking to delete nodes from. Note I have used this XML example in the past for previous parts of my project. This is in no way a duplicate
<?xml version="1.0"?>
<ArrayOfHighwayRoutingData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<HighwayRoutingData>
<tag>@I80</tag>
<destinationSymbols>
<string>SFO</string>
<string>OAK</string>
<string>EMR</string>
<string>ELC</string>
<string>RIC</string>
<string>SPB</string>
<string>Q185</string>
<string>Q456</string>
<string>ads</string>
<string>ads</string>
</destinationSymbols>
</HighwayRoutingData>
<HighwayRoutingData>
<tag>@SR24</tag>
<destinationSymbols>
<string>OAK</string>
<string>ORI</string>
<string>LFY</string>
<string>WCR</string>
<string>G151</string>
</destinationSymbols>
</HighwayRoutingData>
<HighwayRoutingData>
<tag>@US101</tag>
<destinationSymbols>
<string>SFO</string>
<string>SSC</string>
<string>MIL</string>
<string>PAO</string>
<string>Q185</string>
</destinationSymbols>
</HighwayRoutingData>
</ArrayOfHighwayRoutingData>
CodePudding user response:
*<?php
$doc = new DOMDocument;
$doc->load('theFile.xml');
$thedocument = $doc->documentElement;
//this gives you a list of the messages
$list = $thedocument->getElementsByTagName('message');
//figure out which ones you want -- assign it to a variable (ie: $nodeToRemove )
$nodeToRemove = null;
foreach ($list as $domElement){
$attrValue = $domElement->getAttribute('time');
if ($attrValue == 'VALUEYOUCAREABOUT') {
$nodeToRemove = $domElement; //will only remember last one- but this is just an example :)
}*
}
*//Now remove it.
if ($nodeToRemove != null)
$thedocument->removeChild($nodeToRemove);
echo $doc->saveXML();*
?>
CodePudding user response:
Given the structure of the XML file and the possibility that the same value of string
could exist within several HighwayRoutingData
nodes you need to positively identify the correct parent node from which to delete your selected string
and to that end I'd suggest modifying your generated HTML slightly so that the delete
hyperlink also contains the tag
for that particular HighwayRoutingData
node.
ie:
<a href="delete.php?action=delete&string='.$sym.'&tag='.$tag.'">Delete</a>
And then you can query the DOM to find that tag
and from that point further query within that node to find the selected string
<?php
/****************
delete.php
The hyperlink needs to have the Tag included so that the appropriate
parent node in the XML can be targeted for the delete operation.
*/
error_reporting( E_ALL );
session_start();
if( isset(
$_GET['action'],
$_GET['string'],
$_GET['tag'],
$_SESSION['file']
) ){
$file=$_SESSION['file'] ?: 'RouteSymbol.xml';
if( $_GET['action']=='delete' ){
libxml_use_internal_errors( true ) ;
$dom=new DOMDocument();
$dom->validateOnParse=false;
$dom->recover=true;
$dom->strictErrorChecking=false;
$dom->load( $file );
libxml_clear_errors();
$xp=new DOMXPath( $dom );
/*
Find the appropriate parent node
based upon the given tag.
*/
$root=$dom->getElementsByTagName('ArrayOfHighwayRoutingData')->item(0);
$expr=sprintf( '//HighwayRoutingData/tag[ contains( text(), "%s") ]', urldecode( $_GET['tag'] ) );
$col=$xp->query( $expr );
if( $col && $col->length > 0 ){
/*
now find the string node within the specified parent based
upon string value using `contains(text(),"STRING")`
*/
$dest=$xp->query( 'destinationSymbols', $col->item(0)->parentNode )->item(0);
$expr=sprintf( 'string[ contains( text(), "%s" ) ]', urldecode( $_GET['string'] ) );
$string=$xp->query( $expr, $dest )->item(0);
if( $dest && $string ) $dest->removeChild( $string );
}
$dom->save( urldecode( $file ) );
}
}
?>