1

I have an HTML form that calls a PHP document post_remove.php on submission. post_remove.php checks a hidden input value value="pst_09-12-2014_07:20:11pm"> to find an id attribute that matches in data.xml to be removed. id="pst_01-01-2014_05:00:00pm" I am using a form value to compare. $check = $_POST["validate"] ;

I have tried many alternatives such as loops with no luck and also felt they were unneccesary since I only want one element removed. I can't seem to get any elements to be removed.

My HTML form blog_home.html:

<div class="blog_wrap">
   <p>01-01-2014</p>
   <p>05:00:00pm</p>
   <h1>My first Blog</h1>
   <p>Welcome to my Blog!</p>

   <form method="post" action="post_remove.html">
      <input type="hidden" name="validate" value="pst_01-01-2014_05:00:00pm">
      <input type="submit" name="closer">
   </form>
</div>

My XML document data.xml:

<?xml version="1.0" encoding="UTF-8"?>
<blog>
<posting id="pst_01-01-2014_05:00:00pm">
   <date>01-01-2014</date>
   <time>05:00:00pm</time>
   <title>My first Blog</title>
   <content>Welcome to my Blog!</content>
</posting>
<posting id="pst_02-02-2014_06:00:00pm">
   <date>02-02-2014</date>
   <time>06:00:00pm</time>
   <title>My Second Blog</title>
   <content>Welcome to my Blog!</content>
</posting>
</blog>

My PHP document post_remove.php:

<?php
if ( isset( $_POST["closer"] ) )
   {
   $check = $_POST["validate"] ;

   $doc = new DOMDocument() ;
   $doc -> load( "data.xml" ) ;

   $posting = $doc -> getElementById( $check ) ;// Suspected fault.

   $doc -> removeChild( $posting ) ;
   $doc -> save( "data.xml" ) ;
   header( "Location: blog_home.html" ) ;
   }
?>
Xavier
  • 109
  • 9
  • Sidenote: Your action shows `action="post_remove.html"` but your file is `post_remove.php` - it should be `action="post_remove.php"` – Funk Forty Niner Sep 13 '14 at 04:03
  • @Fred -ii-oops typo from transfering. – Xavier Sep 13 '14 at 04:05
  • why do you have a header redirect above the removing of the nodes? you remove the nodes, then after its complete, redirect – Kevin Sep 13 '14 at 04:13
  • @Ghost I wondered about that. Thanks for the tip. I really felt it should be last in the first place. – Xavier Sep 13 '14 at 04:14
  • @Xavier actually i was trying to answer your question, and also failed, but i found out that you cannot use `getElementById` on XMLs, here a [reading](http://stackoverflow.com/questions/3405117/simplify-php-dom-xml-parsing-how/3405651#3405651) about it if why it is, the only solution presented was thru XPath – Kevin Sep 13 '14 at 04:24
  • @Ghost I do not want to use other Parsers. How about finding a match with `childNode[x]` using a `for()` loop? – Xavier Sep 13 '14 at 04:28
  • @Xavier well whatever works for you, xpath is actually nice though and that i will recommend, but if you want to loop it then go for it :) – Kevin Sep 13 '14 at 04:30
  • @Ghost Well I tried the loop route and could not get a resulting removed element. I also tried the `foreach()` loop. – Xavier Sep 13 '14 at 04:32
  • @Xavier derp's answer is the most feasible +1, i suggest take that route – Kevin Sep 13 '14 at 04:36

1 Answers1

2

Just because the attribute name is id does not mean the DOM assumes the attribute to be of type id. Per the PHP manual entry on getElementById:

For this function to work, you will need either to set some ID attributes with DOMElement::setIdAttribute or a DTD which defines an attribute to be of type ID. In the later case, you will need to validate your document with DOMDocument::validate or DOMDocument::$validateOnParse before using this function.

If you don't feel like creating a DTD to specify that @id is indeed an ID you can use an XPath expression to easily grab the elements where the attribute matches.

Like so:

$doc = new DOMDocument() ;
$doc -> load( "data.xml" ) ;

$xpath = new DOMXPath($doc);

$postings = $xpath->query("/blog/posting[@id='$check']");
foreach ($postings as $posting) {
    $posting->parentNode->removeChild($posting);
}

$doc -> save( "data.xml" ) ;

Note: You also don't remove the child from the DOMDocument itself, but instead from the child's parent node.

user3942918
  • 25,539
  • 11
  • 55
  • 67