Remove XML parent node based on value of child node with php domdocument

I've tried everything I could find and think of to get this working correctly, to no avail.  I'm trying to delete an xml node based on the node value of one of it's children (entrynum).  Again, I've tried several different approaches and variations of them with no success.  The logic seems correct, but I've been getting inexplicable output with no errors.  I've gotten close, but still with erratic, unpredictable behavior.  Here's where I'm at with it now (my latest attempt anyway).  Any suggestions.  Thanks in advance.

The XML in entries.xml:

<?xml version="1.0" encoding="utf-8"?>
<entries>
  <entry>
    <title>0</title>
    <entrydate>0</entrydate>
    <contents>0</contents>
    <entrynum>0</entrynum>
  </entry>
  <entry>
    <title>1</title>
    <entrydate>1</entrydate>
    <contents>1</contents>
    <entrynum>1</entrynum>
  </entry>
  <entry>
    <title>2</title>
    <entrydate>2</entrydate>
    <contents>2</contents>
    <entrynum>2</entrynum>
  </entry>
  <entry>
    <title>3</title>
    <entrydate>3</entrydate>
    <contents>3</contents>
    <entrynum>3</entrynum>
  </entry>
</entries>

Open in new window


And here's the php: (if entrynum = $GLOBALS[num] I want that node removed when the script runs).

$entries = new DOMDocument('1.0', 'utf-8');
	$entries->formatOutput = true;
	$entries->preserveWhiteSpace = true;
	$entries->load('entries.xml');

	$entry_node = $entries->getElementsByTagName("entries")->item(0);
	
	
	foreach($entry_node->getElementsByTagName("entry") as $node){
	if($node->getElementsByTagName("entrynum")->nodeValue = $GLOBALS['num']){
	$node->parentNode->removeChild($node);}}
		
		
	$entries->save('entries.xml');

Open in new window

KaiserOwnerAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ray PaseurCommented:
Please see: http://iconoun.com/demo/temp_kwkened.php
<?php // demo/temp_kwkened.php
error_reporting(E_ALL);

// SEE http://www.experts-exchange.com/Web_Development/WebApplications/Q_28511238.html

// TEST DATA
$xml = <<<EOD
<?xml version="1.0" encoding="utf-8"?>
<entries>
  <entry>
    <title>0</title>
    <entrydate>0</entrydate>
    <contents>0</contents>
    <entrynum>0</entrynum>
  </entry>
  <entry>
    <title>1</title>
    <entrydate>1</entrydate>
    <contents>1</contents>
    <entrynum>1</entrynum>
  </entry>
  <entry>
    <title>2</title>
    <entrydate>2</entrydate>
    <contents>2</contents>
    <entrynum>2</entrynum>
  </entry>
  <entry>
    <title>3</title>
    <entrydate>3</entrydate>
    <contents>3</contents>
    <entrynum>3</entrynum>
  </entry>
</entries>
EOD;

// DELETION SIGNAL (if entrynum = $GLOBALS[num]
$GLOBALS['num'] = 2;

// MAKE AN OBJECT
$obj = SimpleXML_Load_String($xml);

// REMOVE THE NODE
unset($obj->entry[$GLOBALS['num']]);

// RECOVER THE XML AND SHOW THE WORK PRODUCT
$new = $obj->AsXML();
echo '<pre>' . htmlentities($new);

Open in new window

0
KaiserOwnerAuthor Commented:
Hi Ray,

Thank you for the response.  To be sure I understand, when removing the node with
unset($obj->entry[$GLOBALS['num']]);

Open in new window

 won't this remove the node based on its position in the xml tree?  What I'd like to do is remove a child node (entrynum) of the entry node.  So something like this:  
$obj->entry->entrynum

Open in new window

to target the child node.  But to delete that child node based on its value rather than its position, how should I target its value?
0
Ray PaseurCommented:
Ahh, I get it - coincidental alignment.  Let me get another code sample for you.
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

KaiserOwnerAuthor Commented:
Ray,

I need to be able to remove the entry node based on the value of entrynum, so that when entry nodes are removed I can still remove the desired node based on the value of entrynum, because every time a node is removed, the remaining nodes below it move up a position, so targeting their position in the xml tree won't work.  Hope I'm explaining that clearly.  Thanks again.

<entries>
  <entry>
    <title>0</title>
    <entrydate>0</entrydate>
    <contents>0</contents>
    <entrynum>0</entrynum>
  </entry>
  <entry>
    <title>2</title>
    <entrydate>2</entrydate>
    <contents>2</contents>
    <entrynum>2</entrynum>
  </entry>
  <entry>
    <title>6</title>
    <entrydate>6</entrydate>
    <contents>6</contents>
    <entrynum>6</entrynum>
  </entry>
  <entry>
    <title>3</title>
    <entrydate>3</entrydate>
    <contents>3</contents>
    <entrynum>3</entrynum>
  </entry>
</entries>

Open in new window

0
KaiserOwnerAuthor Commented:
Yes exactly, coincidental alignment.  I should have presented it more clearly.
0
Ray PaseurCommented:
Try this.  Note the use of "foo" in the script.

<?php // demo/temp_kwkened.php
error_reporting(E_ALL);

// SEE http://www.experts-exchange.com/Web_Development/WebApplications/Q_28511238.html

// TEST DATA
$xml = <<<EOD
<?xml version="1.0" encoding="utf-8"?>
<entries>
  <entry>
    <title>0</title>
    <entrydate>0</entrydate>
    <contents>0</contents>
    <entrynum>0</entrynum>
  </entry>
  <entry>
    <title>1</title>
    <entrydate>1</entrydate>
    <contents>1</contents>
    <entrynum>1</entrynum>
  </entry>
  <entry>
    <title>2</title>
    <entrydate>2</entrydate>
    <contents>2</contents>
    <entrynum>foo</entrynum>
  </entry>
  <entry>
    <title>3</title>
    <entrydate>3</entrydate>
    <contents>3</contents>
    <entrynum>bar</entrynum>
  </entry>
</entries>
EOD;

// DELETION SIGNAL (if entrynum = $GLOBALS[num]
$GLOBALS['num'] = 'foo';

// MAKE AN OBJECT
$obj = SimpleXML_Load_String($xml);

// USE A COUNTING ITERATOR TO FIND THE ELEMENT WE WANT TO DELETE
$cnt = 0;
foreach ($obj as $ent)
{
    if ($ent->entrynum == $GLOBALS['num'])
    {
        unset($obj->entry[$cnt]);
    }
    $cnt++;
}

// RECOVER THE XML AND SHOW THE WORK PRODUCT
$new = $obj->AsXML();
echo '<pre>' . htmlentities($new);

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
KaiserOwnerAuthor Commented:
Wow!  Simply awesome.  I tried using a counter like that to cycle through the nodes and test the condition, but with a while loop.  This is great, thank you!
0
Ray PaseurCommented:
Thanks for the points - it's a great question, ~Ray
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Applications

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.