Page 1 of 1

Sub-Nodes in XML - How?

Posted: Sat Nov 10, 2007 7:05 pm
by Jonah Bron
Hi,

I would like to know how to parse sub-nodes in XML (DOM). I tried:

Code: Select all

$xml = new DOMDocument('1.0');
$xml->load('file.xml');
$root = $xml->documentElement;
$node = $root->firstChild;
$sub_node = $node->firstChild;
while ($node){
    if ($node->nodeType==XML_ELEMENT_NODE && $node->nodeName=='node'){
        while ($sub_node){
            if ($sub_node->nodeType==XML_ELEMENT_NODE && $sub_node->nodeName=='sub_node'){
                echo $sub_node->firstChild->nodeValue;
            }
            $sub_node = $sub_node->nextSibling;
        }
    }
    $node = $node->nextSibling;
}
$xml->saveXML();
But it doesn't work. How do I get it to?

Thanks

Posted: Sat Nov 10, 2007 7:15 pm
by Christopher
You may want to do this to see what is in the node vars returned by the XML library, then you will know how to iterate through it:

Code: Select all

echo '<pre>' . print_r($node, 1) . '</pre>';

Posted: Sat Nov 10, 2007 7:22 pm
by Jonah Bron
The node just contains the sub-nodes, and the sub-nodes only contain text. That I know. Maybe I'm just confused. :?

Posted: Sat Nov 10, 2007 7:38 pm
by Christopher
Which part if the code you posted do you think is not working? What is it not doing that you expect it to do? What is the XML you are parsing?

Posted: Sat Nov 10, 2007 8:34 pm
by Jonah Bron
The php above was simply an example of something more complicated I'm trying to do. I am attempting to manually write an index for my blog(it is very small), with parameters: name, description(desc), keywords(keys), and address. This will be used by a search results page (this is the page), that will take a search term brought in with GET, exploded into an array, and looped through with a while statement, using the eregi() function, to search the name, desc, and keywords for each word in the search, and if it does, it returns an output for that page, and if no results are found, that is stated:

Code: Select all

<?php

//Search is supposed to be $_GET['q'], but for example purposes, it will be:
$search = "learn XML";

$xml = new DOMDocument('1.0');//New Document
$xml->load('search.xml');//Load "search.xml"
$xml->formatOutput = true;//format output

//function for checking relevancy
function getC($from,$str){
$search = explode(' ',$str);//explode search term into array
$a = count($search);//get length of array
$x = 0;//preliminary var for loop
$y = 0;//another one
while ($y>$a){//while $x is less than the length of the array
if ($from.eregi($search[$x])){//if the node eregi()s any words in the search array,
$x = 1;//make preliminary var equal to 1
}
$y += 1;//add 1 to preliminary var
}
if ($x==1){//if preliminary var equals 1
return true;//return true
}else{//but if it equals 0,
return false;//return false
}
}

//Set tree
$root = $xml->documentElement;//root
$page = $root->firstChild;//each page
$doc = $page->firstChild;//each property of each page
$x = 0;
while ($page){//while there is a node to examin
  if ($page->nodeType==XML_ELEMENT_NODE && $page->nodeName=='page'){//if nodetype is correct, and nodename is "page"
  //if any of the sub-node include the search string,
    if ((getC($page->firstChild->nodeValue,$search)==true) || (getC($page->firstChild->nextSibling->nodeValue,$search)==true) || (getC($page->firstChild->nextSibling->nextSibling->nodeValue,$search)==true)){
     $x=1;//make it so it doesn't say "no results found"
      while ($doc){//loop through properties
        if ($doc->nodeType==XML_ELEMENT_NODE){//if nodetype is correct
          if ($doc->nodeName=='name'){//if name is "name"
            //output title, as a link to the "address" property
            echo '<h3><a href="'.$doc->nextSibling->nextSibling->nextSibling->firstChild->nodeValue.'"">'.$doc->firstChild->nodeValue.'</a></h3>';
          }elseif ($doc->nodeName=='desc'){//if name is "desc"
            //output description
            echo '<blockquote>'.$doc->firstChild->nodeValue.'</blockquote><br />';
          }elseif ($page->nodeName=='address'){//if name is "address"
            //output address, as a link
            echo '<a href="'.$doc->firstChild->nodeValue.'">'.$doc->firstChild->nodeValue.'</a>';
          }
        }
        //goto next sibling
        $doc = $doc->nextSibling;
      }
    }
  }
  //goto next sibling
  $page = $page->nextSibling;
}
if ($x==0){//if no results fount, say so
echo "No results found for your search";
}
//close xml doc
$xml->saveXML();//close XML doc
?>
This is an excerpt from the XML index:

Code: Select all

<?xml version="1.0" ?>
<index>
  <page>
    <name>jBlog home page</name>
    <desc>Learn about computers, the internet, web design, and more</desc>
    <keys>Learn XML PHP HTML CSS JS web design internet network computers computer</keys>
    <address>/blog</address>
  </page>
  <page>
    <name>Web Design - jBlog</name>
    <desc>Read about me, learn HTML, CSS, JS, PHP, and XML</desc>
    <keys>XML HTML learn CSS JS PHP web design</keys>
    <adress>/blog/web</address>
  </page>
</index>
P.S. When I learn more, I'd like to, in the future, make meta tags in each page or something for the parameters, and a crawlbot. I've got plenty of time to spare :wink:
Thanks for your help so far :)