Page 1 of 1

recursive function - how to read xml

Posted: Mon Aug 31, 2009 8:00 pm
by claudioivp
Hello everybody!
I'm trying to create a function to read a xml file.
But I have problems to detect folders inside in folders automatically.
I made a code to read the xml, but now I need to make it in a recursive mode.

Help! Help! Help! Please please please!

-bookmarks.xml

Code: Select all

 
<?xml version="1.0" encoding="UTF-8"?>
<ul>
    <li>
        <h3>Newspaper</h3>
        <ul>
            <li>
                <h3>Brazil</h3>
                <ul>
                    <li><a href="http://www.globo.com">globo.com</a></li>
                    <li><a href="http://www.terra.com.br">Terra - What is yours?</a></li>
                    <li><a href="http://www.uol.com.br">Uol - The Best Web</a></li>
                    <li><a href="http://www.brturbo.com.br">IG - The world is who does</a></li>
                </ul>
            </li>
            <li>
                <h3>Eua</h3>
                <ul>
                    <li><a href="http://www.cnn.com">CNN</a></li>
                    <li><a href="http://www.nytimes.com">The New York Times</a></li>
                </ul>
            </li>
            <li><a href="http://www.china.cn">China Newspaper</a></li>
        </ul>
    </li>
    <li>
        <h3>E-mails</h3>
        <ul>
            <li><a href="http://www.gmail.com">Gmail</a></li>
            <li><a href="http://www.hotmail.com">Hotmail</a></li>
        </ul>
    </li>
    <li><a href="http://www.yahoo.com.br">Yahoo! Brasil</a></li>
    <li><a href="http://www.g1.com.br">G1 - Globo</a></li>
</ul>
 
-index.php

Code: Select all

 
<?php
error_reporting(E_ALL);
$reader = new XMLReader(); 
$reader->open("bookmarks.xml");
 
$dados = xml2assoc($reader);
 
//echo("<pre>");
//print_r($dados);
//echo("</pre>");
 
echo "\n<ul>\n";
for($i = 0; $i < count($dados); $i++)
{
    for($j = 0; $j < count($dados[$i])-1; $j++)
    {
        for($k = 0; $k < count($dados[$i]['value']); $k++)
        {
            for($l = 0; $l < count($dados[$i]['value'][$k])-1; $l++)
            {
                for($m = 0; $m < count($dados[$i]['value'][$k]['value']); $m++)
                {
                    $dadoatual = $dados[$i]['value'][$k]['value'][$m];
                    if($dadoatual['tag']  == "h3")
                    {
                        echo "<li>";
                        echo "<h3>";
                        echo $dadoatual['value'];
                        echo "</h3>";
                    }
                    elseif($dadoatual['tag']  == "a")
                    {
                        echo "<li><a href=\"#\">";
                        echo $dadoatual['value'];
                        echo "</a></li>";
                    }
                    elseif($dadoatual['tag']  == "ul")
                    {
                        echo "<ul>";
                        for($n = 0; $n < count($dadoatual['value']); $n++)
                        {
                            for($o = 0; $o < count($dadoatual['value'][$n]); $o++)
                            {
                                if(isset($dadoatual['value'][$n]['value'][$o]['tag']) && $dadoatual['value'][$n]['value'][$o]['tag'] == "h3")
                                {
                                    echo "<li>";
                                    echo "<h3>";
                                    echo $dadoatual['value'][$n]['value'][$o]['value'];
                                    echo "</h3>";
                                }
                                elseif(isset($dadoatual['value'][$n]['value'][$o]['tag']) && $dadoatual['value'][$n]['value'][$o]['tag'] == "a")
                                {
                                    echo "<li><a href=\"#\">";
                                    echo $dadoatual['value'][$n]['value'][$o]['value'];
                                    echo "</a></li>";   
                                }
                                elseif(isset($dadoatual['value'][$n]['value'][$o]['tag']) && $dadoatual['value'][$n]['value'][$o]['tag'] == "ul")
                                {
                                    echo "<ul>";
                                    for($p = 0; $p < count($dadoatual['value'][$n]['value'][$o]['value']); $p++)
                                    {
                                        for($q = 0; $q < count($dadoatual['value'][$n]['value'][$o]['value'][$p])-1; $q++)
                                        {
                                            for($r = 0; $r < count($dadoatual['value'][$n]['value'][$o]['value'][$p]['value']); $r++)
                                            {
                                                if($dadoatual['value'][$n]['value'][$o]['value'][$p]['value'][$r]['tag'] == "a")
                                                {
                                                    echo "<li><a href=\"#\">";
                                                    echo $dadoatual['value'][$n]['value'][$o]['value'][$p]['value'][$r]['value'];
                                                    echo "</a></li>";
                                                }
                                            }
                                        }
                                    }
                                    echo "</ul>";
                                    echo "</li>";
                                }
                            }
                        }
                        echo "</ul> ";
                        echo "</li>";
                    }
                }
            }
        }
    }
}
echo "\n</ul>\n";
 
function xml2assoc($xml) { 
    $tree = null; 
    while($xml->read()) 
        switch ($xml->nodeType) { 
            case XMLReader::END_ELEMENT: return $tree; 
            case XMLReader::ELEMENT: 
                $node = array('tag' => $xml->name, 'value' => $xml->isEmptyElement ? '' : xml2assoc($xml)); 
                if($xml->hasAttributes) 
                    while($xml->moveToNextAttribute()) 
                        $node['attributes'][$xml->name] = $xml->value; 
                $tree[] = $node; 
            break; 
            case XMLReader::TEXT: 
            case XMLReader::CDATA: 
                $tree .= $xml->value; 
        } 
    return $tree; 
} 
?>
 

Re: recursive function - how to read xml

Posted: Mon Aug 31, 2009 10:46 pm
by requinix
Doing lots of loops like that is not the way. When you're getting to two or three nested loops you should start wondering if there's an alternative.

So we don't have to crawl through all that, what are you trying to do? What should the output look like?

Re: recursive function - how to read xml

Posted: Tue Sep 01, 2009 7:57 am
by Paul_F
You might find some useful info here.

I agree w/tasairis. And if you NEED that many loops to traverse through your data, they should be well documented, IMHO. Nicely structured tho!

Re: recursive function - how to read xml

Posted: Thu Sep 03, 2009 7:37 pm
by claudioivp
I agree with you.
It's for this, that I need to make a function recursive; to eliminate these lots of loops.

Map:
-read the xml;
-detect folders, and detect folders inside in folders...etc;
-for each folder detected, read the links;
-save in array all detected links with respective folders like tags for each link.
-save in MySQL.

For sample, after de applied the recursive function, the final result to the xml above would be:

Read[0]["link"]:
http://www.globo.com
Read[0]["tags"][0]:
Newspaper
Read[0]["tags"][1]:
Brazil

Read[1]["link"]:
http://www.terra.com.br
Read[1]["tags"][0]:
Newspaper
Read[1]["tags"][1]:
Brazil

[...]
[...]

Read[4]["link"]:
http://www.cnn.com
Read[4]["tags"][0]:
Newspaper
Read[4]["tags"][1]:
Eua

[...]

Read[6]["link"]:
http://www.china.cn
Read[6]["tags"][0]:
Newspaper

Read[7]["link"]:
http://www.gmail.com
Read[7]["tags"][0]:
E-mails

[...]

Read[9]["link"]:
http://www.yahoo.com.br

Read[10]["link"]:
http://www.g1.com.br