removing xml element

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
mavedog21
Forum Newbie
Posts: 23
Joined: Thu Dec 21, 2006 1:27 pm

removing xml element

Post by mavedog21 »

Hey all,

I'm having a problem with deleting an element that contains a childNodes->value with a $variable == $_POST['id'].
I've searched and found where you can get the content of a childNodes but nothing about deleting it's parent.
Does anybody know where I could look?

I've tried piecing together functions from http://www.php.net but nothing is exactly what I'm looking for.
Needing guidance not so much the code (though not going to bock at it).
(example help: Check out a specific tutorial or try using blah, blah, blah functions)

Any help would be great.
Thanks a ton,

sky


OH, here's what I'm trying as of now:

Code: Select all

$toDelete = $_POST['id'];
$home = $dom->documentElement;

$house = $home->getElementsByTagName('house');
// collects all the "house" elements in my rootNode "home"

$id = $house->getElementsByTagName('id');
// collects all "id" elements in $house variable

if($id == $toDelete){
//$id = $home->remove_child('$home');
 echo "id is the answer";

}else if($houseOne == $toDelete){
 echo "houseOne is the answer";

 }else if($house == $toDelete){
 echo "house is the answer";

 }else{
 echo "These are not the answers";
}
Sample XML:

Code: Select all

<home>
   <house>Tom's House</house>
           <id>1234</id>
   </house>
</home>
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

The sample is invalid xml.

try

Code: Select all

$dom = DOMDocument::loadxml("<home>
		<house>
			<name>Bob's House</name>
			<id>1233</id>
		</house>
		<house>
			<name>Tom's House</name>
			<id>1234</id>
		</house>
		<house>
			<name>John's House</name>
			<id>1235</id>
		</house>
	</home>");


$xpath = new DOMXPath($dom);

// all house elements having an id-element with the text()-representation 1234
$nodeset = $xpath->query('//house[id="1234"]');
if ( 0<$nodeset->length ) {
	$dom->documentElement->removeChild($nodeset->item(0));
}

echo $dom->savexml();
mavedog21
Forum Newbie
Posts: 23
Joined: Thu Dec 21, 2006 1:27 pm

Post by mavedog21 »

I tried the code you offered but to no avail.

I get a nodeset equal to -1 even though there is a nodeset that is equal to the
id number supplied.

I believe my problem is somewhere in this code snippet

Code: Select all

$nodeset = $xpath->query('//house[id="1234"]'); 
if ( 0<$nodeset->length ) { 
        $dom->documentElement->removeChild($nodeset->item(0)); 
}
I also wanted it to equal a set variable. Is this how you would code it?

Code: Select all

$toDelete = $_POST['id'];

$nodeset = $xpath->query("//house[id= $toDelete ]"); 
if ( 0<$nodeset->length ) { 
        $dom->documentElement->removeChild($nodeset->item(0)); 
}
It appears to me that it's not finding my id value even if it's hard coded in instead of using a variable.
I used this to test it.

Code: Select all

$toDelete = $_POST['id'];  // id number set from a posted html form.

$nodeset = $xpath->query("//house[id= $toDelete ]"); 
if ( -1<$nodeset->length ) { 
        echo "-- the length is -1 --";
        $dom->documentElement->removeChild($nodeset->item(0)); 
}if ( 0<$nodeset->length ) { 
    echo "-- the length is 0 --"
        $dom->documentElement->removeChild($nodeset->item(0)); 
}
and it comes back with

Code: Select all

-- the length is -1 --
any ideas?
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

Please try the example without any changes first. It's working fine for me.
If it doesn't work, what's the output of

Code: Select all

<?php
echo 'version: ', phpversion(), "<br />\n";
echo 'uname: ', php_uname('s r v m'), "<br />\n";
echo 'libxml: ', defined('LIBXML_VERSION') ? LIBXML_VERSION : '--', "<br />\n";
foreach( get_loaded_extensions() as $e ) {
	if ( false!==strpos($e, 'xml') || false!==strpos($e, 'dom') ) {
		echo 'extension: ', $e, "<br />\n";
	}
}
btw:
volka wrote:$nodeset = $xpath->query('//house[id="1234"]');
mavedog21 wrote:$nodeset = $xpath->query("//house[id= $toDelete ]");
note the missing quotes arround the right value of the equal sign.
mavedog21
Forum Newbie
Posts: 23
Joined: Thu Dec 21, 2006 1:27 pm

Post by mavedog21 »

I tried it first without changes and the result was just <house><house><house>.
I can't try the code you just provide until tonight. When I get on my home computer
I do know I'm running php5 if that helps.

Also for the variable inside a string would it read this way then?

Code: Select all

$nodeset = $xpath->query('//house[id= "$toDelete" ]');
I didn't add the quotes because of this quote:
Creating a string
To declare a string in PHP you can use double quotes ( " ) or single quotes ( ' ). There are some differences you need to know about using these two. If you're using double-quoted strings variables will be expanded ( processed ).
from http://www.php-mysql-tutorial.com/php-t ... trings.php

My understanding to that was a double quoted strings such as

Code: Select all

("//house[id= $toDelete ]");
would process out (read the $_POST variable info) that is stored in the $toDelete variable.
Is this true?

thanks for the help.
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

For php there's no difference between 'foobar' , 'SELECT x,y,z FROM ..' or '//house[id="1234"]'. It really doesn't care about the contents.
But this isn't about php, php doesn't complain about the string. You're passing that string to another parser, in this case to the xpath parser of libxml2. And you have to mark the string 1234 for it. On the other hand the xpath parser does not care about how the string was build.

Code: Select all

$xpath->query('//house[id="1234"]');
// or
$xpath->query('//house[id="' . '1234'. '"]');
// or
$query = '//house[id="' . '1234'. '"]';
$xpath->query($query);
// or
$var = '1234';
$query = '//house[id="' . (int)$var . '"]';
$xpath->query($query);
the method query() always gets the string //house[id="1234"] passed.

try

Code: Select all

$query = '//house[id="'.$toDelete.'"]';
$xpath->query($query);
mavedog21
Forum Newbie
Posts: 23
Joined: Thu Dec 21, 2006 1:27 pm

Post by mavedog21 »

volka, I don't know what I did wrong earlier but your code DID delete the element with the childNode id of 1234. Sorry about my confusion.

Now, when I try to use my own xml file and delete an element it will not work.
How would I delete my elements from my own (external xml) file?
I've set my $dom to load my xml file. Would the whole php code would look like this:

Code: Select all

<?php
$dom = new DomDocument;

$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->load('thexml.xml');

$toDelete = $_POST['id'];

$xpath = new DOMXPath($dom);
$query = '//house[id="'.$toDelete.'"]';

// all house elements having an id-element with the text()-representation 1234 
$nodeset = $xpath->query($query);
//$nodeset = $xpath->query("//house[id=$toDelete]");


########### Testing the Return Length ######################

if ( -1<$nodeset->length ) { 
  echo "the nodeset length is -1";
        //$dom->documentElement->removeChild($nodeset->item(0)); 
} elseif (0<$nodeset->length ) { 
    echo "the nodeset length is 0"
        //$dom->documentElement->removeChild($nodeset->item(0)); 
}

###################################################

echo $dom->savexml();

?>
There must be a problem with this because I tried it this morning and it still returns -1 as the nodeset length.
What could be causing that? Even when I keep the id value hardcoded like you did with yours:

Code: Select all

$nodeset = $xpath->query('//house[id="1234"]');
It still returned a -1 nodeset length.
Any ideas?
Post Reply