0

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>

3 Answers 3

1

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>
Sign up to request clarification or add additional context in comments.

Comments

0

As flight is an $item, you should remove $item and not $node:

$item->parentNode->removeChild($item);

Comments

0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.