Reputation: 1108
i'm trying to remove a specific node from XML using PHP. This is the structure of the XML :
<ArrivingFlights>
<flight>
<to>Michelle</to>
<from>Brianna xx</from>
<imagepath>0001.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>17:00</time>
<date>18/12/15</date>
</flight>
<flight>
<to>Ger</to>
<from>Mammy xx</from>
<imagepath>0002.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>08:00</time>
<date>21/12/15</date>
</flight>
<flight>
<to>Ciara</to>
<from>Vikki xx</from>
<imagepath>0003.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>11:00</time>
<date>17/12/15</date>
</flight>
</ArrivingFlights>
I have a PHP file that im using to get a FileName so i can remove a node based on that file name and replace it. This is my PHP :
<?php
$id = $_GET['imagepath'];
$xmldoc = new DOMDocument();
$xmldoc->load('newcoke.xml');
$root = $xmldoc->documentElement;
$fnode = $root->firstChild;
// we retrieve the chapter and remove it from the book
$items = $xmldoc->getElementsByTagName('flight');
foreach ($items as $item){
$node = $item->getElementsByTagName('imagepath')->item(0);
if ($node->nodeValue == $id){
$node->parentNode->removeChild($node);
}
}
$xmldoc->save('newXmlFile.xml');
?>
This SORT OF works, when i look at newFile.xml it is removing "ImagePath" but i wanted it to remove that whole "flight" node, so basically its parent. This is the result i get if i pass it 0001.jpg :
<flight>
<to>Michelle</to>
<from>Brianna xx</from>
<templateStyle>template1</templateStyle>
<time>17:00</time>
<date>18/12/15</date>
</flight>
<flight>
<to>Ger</to>
<from>Mammy xx</from>
<imagepath>0002.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>08:00</time>
<date>21/12/15</date>
</flight>
<flight>
<to>Ciara</to>
<from>Vikki xx</from>
<imagepath>0003.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>11:00</time>
<date>17/12/15</date>
</flight>
Upvotes: 0
Views: 140
Reputation: 107567
Consider using XSLT, the special-purpose language that restructures XML files. PHP maintains an XSLT 1.0 processor. Hence, there is no need for a foreach
loop or if
logic conditioning as the stylesheet script will handle such processing and very efficiently. You can even embed the script in PHP to dynamically pass the $id
variable:
PHP with embedded XSLT
// Retrieve imagepath value
$id = $_GET['imagepath'];
// Load the XML source
$doc = new DOMDocument();
$doc->load('Flights.xml');
// Parse XSLT
$xsl = new DOMDocument;
$xslstr = '<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<!-- Identity Transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="flight[imagepath=\''.$id.'\']"/>
</xsl:transform>';
$xsl->loadXML($xslstr);
// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// Transform XML source
$newXml = $proc->transformToXML($doc);
// Save output to file
$xmlfile ='Output.xml';
file_put_contents($xmlfile, $newXml);
Output
<?xml version="1.0" encoding="UTF-8"?>
<ArrivingFlights>
<flight>
<to>Ger</to>
<from>Mammy xx</from>
<imagepath>0002.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>08:00</time>
<date>21/12/15</date>
</flight>
<flight>
<to>Ciara</to>
<from>Vikki xx</from>
<imagepath>0003.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>11:00</time>
<date>17/12/15</date>
</flight>
</ArrivingFlights>
Upvotes: 1
Reputation: 13127
You can use parentNode
as many times as you need to, although obviously it requires you to be confident your XML structure won't change. In this particular case you just need to go up one level further, like this:
$node->parentNode->parentNode->removeChild($node->parentNode);
But seeing as you're already in a loop where $item
is being set, just remove that directly:
$item->parentNode->removeChild($item);
Upvotes: 0
Reputation: 54831
As flight
is an $item
, you should remove $item
and not $node
:
$item->parentNode->removeChild($item);
Upvotes: 0