Sub-Nodes in XML - How?

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
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Sub-Nodes in XML - How?

Post 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
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post 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>';
(#10850)
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Post 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. :?
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post 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?
(#10850)
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Post 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 :)
Post Reply