Jump to content


Photo

DOM trouble


  • Please log in to reply
2 replies to this topic

#1 448191

448191
  • Staff Alumni
  • Advanced Member
  • 3,545 posts
  • LocationNetherlands

Posted 20 April 2006 - 10:52 AM

I'm struggling to master parsing xml using php5's DOM class...

Simple xml file:
<?xml version="1.0"?>
<dbconfig.xml>
    <host>
        <name>localphp4</name>
        <user>
            <level>admin</level>
            <name>root</name>
        </user>
    </host>  
    <pass>kjhgkfdh</pass>
</dbconfig.xml>

I've got this function this function that gets an element with:
$doc->getElementsByTagname($request) as $element)

That works fine, the first element returned when I request 'host' returns the following with this piece of code:
echo 'This node "'.$node->nodeName.'" is a "type '.$node->nodeType.'" node, child of "'
   .$node->parentNode->nodeName.'". It\'s value: "'.$node->nodeValue.'".<br />';
Prints:
[!--quoteo--][div class=\'quotetop\']QUOTE[/div][div class=\'quotemain\'][!--quotec--]This node "host" is a "type 1" node, child of "dbconfig.xml". It's value: " localphp4 admin root ".[/quote]

So far so good!

Then I want to loop through the children.
I use $node->childNodes; in a loop to try and get elements "name" and "user".

However it only loops once (as confirmed by count($node->childNodes) resulting in "1"), and claims this only child is of type DOMText (and empty):

[!--quoteo--][div class=\'quotetop\']QUOTE[/div][div class=\'quotemain\'][!--quotec--]This node "#text" is a "type 3" node, child of "host". It's value: " ".[/quote]

Shoot me, I don't get it.


Oh, I forgot to mention that I did check for whitespaces, as I read somewhere they can cause problems..

#2 448191

448191
  • Staff Alumni
  • Advanced Member
  • 3,545 posts
  • LocationNetherlands

Posted 20 April 2006 - 11:57 AM

Ok, let me try to walk myself trough this.... If anyone wants to jump in, please (nah, really PLEASE) jump in.

I instantiate a new DOMDocument object and load a file:
$doc = new DOMDocument();
$doc->load($file);
So now $doc is an object of class DOMDocument.

What I do next is foreach($doc->getElementsByTagname($request) as $element)...

So I should be looping through the the nodelist fetching objects of class DOMNode. A node can be several things like an element, text, atrribute, document, comment etc, as can be read by DOMNode->nodeType...

Here's where I get confused again. If I'm fetching nodes, why is the method named getElements???
Nevermind.. I get it: because you are fetching nodes by tagname you get a list of nodes that are elements.. I apologize..

How does this nodelist thing behave anyway?

[!--quoteo--][div class=\'quotetop\']QUOTE[/div][div class=\'quotemain\'][!--quotec--]The DOMNodeList interface provides the abstraction of an ordered collection of nodes.
DOMNodeLists are created by DOMDocument::getElementsByTagName(), DOMNode::getChildNodes(),

The items in the DOMNodeList are accessible via an integral index, starting from 0.[/quote]

So basicly it behaves just like a numeric array of objects. Which doesn't really help, since I was already treating it that way... sigh...

Next thing I get the currents' node children: foreach(($element->childNodes) as $node)
This also iterates through a nodelist...

[!--sizeo:3--][span style=\"font-size:12pt;line-height:100%\"][!--/sizeo--]I'm not getting anywhere with this.... anyone care to step in?[!--sizec--][/span][!--/sizec--]

#3 448191

448191
  • Staff Alumni
  • Advanced Member
  • 3,545 posts
  • LocationNetherlands

Posted 20 April 2006 - 01:17 PM

Just to illustrate how I try to use this:

function dump_arr($arr)
{
    print '<pre>';
    print_r($arr);
    print '</pre>';
    echo '<br />';
}
function xml_test()
{
    $file = $_SERVER['DOCUMENT_ROOT'].'/config/dbconfig.xml';
    $doc = new DOMDocument();
    $doc->load($file);
    foreach($doc->getElementsByTagname('host') as $node)
    {
        $arr[$node->nodeName] = array();
        function loop($node, $arr)
        {
            foreach(($node->childNodes) as $cnode)
            {
                //If the child has children of it's own:
                if($cnode->childNodes) 
                    return loop(array_merge($cnode,$arr,array($cnode->nodeName=>array())));
                else
                    return array_merge($arr,array($cnode->nodeName=>$cnode->nodeValue));
            }
        }
        $ret = loop($node,$arr);
    }
    dump_arr($ret);
}
xml_test();

Currently this prints
[!--quoteo--][div class=\'quotetop\']QUOTE[/div][div class=\'quotemain\'][!--quotec--]Array
(
[host] => Array
(
)

[#text] =>

)[/quote]

Which is terribly wrong for more than one reason... :(






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users