Jump to content

Archived

This topic is now archived and is closed to further replies.

448191

DOM trouble

Recommended Posts

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

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

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

That works fine, the first element returned when I request 'host' returns the following with this piece of code:
[code]echo 'This node "'.$node->nodeName.'" is a "type '.$node->nodeType.'" node, child of "'
   .$node->parentNode->nodeName.'". It\'s value: "'.$node->nodeValue.'".<br />';[/code]
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 [u]$node->childNodes;[/u] in a loop to try and get elements "name" and "user".

However it only loops once (as confirmed by [u]count($node->childNodes)[/u] 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..

Share this post


Link to post
Share on other sites
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:
[code]$doc = new DOMDocument();
$doc->load($file);[/code]
So now $doc is an object of class DOMDocument.

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

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 get[u]Elements[/u]???
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: [u]foreach(($element->childNodes) as $node)[/u]
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--]

Share this post


Link to post
Share on other sites
Just to illustrate how I try to use this:

[code]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();[/code]

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... :(

Share this post


Link to post
Share on other sites

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.