Page 1 of 1

removing xml element

Posted: Thu Feb 08, 2007 10:59 am
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>

Posted: Thu Feb 08, 2007 11:46 am
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();

Posted: Mon Feb 12, 2007 10:50 am
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?

Posted: Mon Feb 12, 2007 11:26 am
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.

Posted: Mon Feb 12, 2007 11:59 am
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.

Posted: Mon Feb 12, 2007 12:16 pm
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);

Posted: Tue Feb 13, 2007 10:27 am
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?