2010-07-06 8 views
-1

J'ai essayé de construire une navigation enfant/parent pendant un petit moment maintenant en utilisant PHP (je suis d'un fond de .net) et je ne peux pas me rapprocher des résultats souhaités. Je charge mes données à partir d'un fichier XML en utilisant SimpleXML avec succès, mais j'essaie de trouver comment je peux mapper cela en tableaux ou en variables afin que je puisse l'écrire.Comment convertir XML en un menu HTML hiérarchique?

<Categories> 
    <Category> 
    <ID>1</ID> 
    <Title>Days</Title> 
    <Description /> 
    <ParentID /> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>2</ID> 
    <Title>Monday</Title> 
    <Description /> 
    <ParentID>1</ParentID> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>3</ID> 
    <Title>Tuesday</Title> 
    <Description /> 
    <ParentID>1</ParentID> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>4</ID> 
    <Title>Wednesday</Title> 
    <Description /> 
    <ParentID>1</ParentID> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>5</ID> 
    <Title>Thursday</Title> 
    <Description /> 
    <ParentID>1</ParentID> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>6</ID> 
    <Title>Friday</Title> 
    <Description /> 
    <ParentID>1</ParentID> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>7</ID> 
    <Title>Saturday</Title> 
    <Description /> 
    <ParentID/> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>8</ID> 
    <Title>Sunday</Title> 
    <Description /> 
    <ParentID/> 
    <Meta /> 
    </Category> 
</Categories> 

foreach($categories as $category) { 

       if ($category->ParentID != "") 
       { 
        echo "<li><a href=index.php?Cat=$category->ID>$category->Title</a></li>"; 
        echo "<ul>"; 
        foreach($categories as $subcategory) { 
        if ($subcategory->ParentID == $category->ID) 
        { 
         echo "<li><a href=index.php?Cat=$subcategory->ID>$subcategory->Title</a></li>"; 
        } 
        } 
        echo "</ul>"; 
       } 
       else 
       { 
        echo "<li><a href=index.php?Cat=$category->ID>$category->Title</a></li>"; 
       } 
      } 
      echo "</ul>"; 

donc ma sortie désirée serait quelque chose comme ceci:

<ul id="p7menubar"> 
<li><a class="trigger" href="#">Days</a> 
<ul> 
<li><a href="#">Monday</a></li> 
<li><a href="#">Tuesday</a></li> 
<li><a href="#">Wednesday</a></li> 
<li><a href="#">Thursday</a></li> 
<li><a href="#">Friday</a></li> 
</ul> 
</li> 
<li><a href="index.htm">Saturday</a></li> 
<li><a href="index.htm">Sunday</a></li> 
</ul> 
+1

Bonjour Unix Man. Il existe trois solutions personnalisées à cette vieille question, et elles ne semblent pas avoir attiré votre attention, vos commentaires, vos votes ou vos acceptations depuis sept ans. Seriez-vous capable de rectifier cela lors de votre prochaine connexion s'il vous plaît? – halfer

Répondre

0

Bien sûr beaucoup d'optimisation nécessaire, mais c'est l'affaire

$str = <<<XML 
<?xml version='1.0'?> 
<Categories> 
    <Category> 
    <ID>1</ID> 
    <Title>Days</Title> 
    <Description /> 
    <ParentID /> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>2</ID> 
    <Title>Monday</Title> 
    <Description /> 
    <ParentID>1</ParentID> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>3</ID> 
    <Title>Tuesday</Title> 
    <Description /> 
    <ParentID>1</ParentID> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>4</ID> 
    <Title>Wednesday</Title> 
    <Description /> 
    <ParentID>1</ParentID> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>5</ID> 
    <Title>Thursday</Title> 
    <Description /> 
    <ParentID>1</ParentID> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>6</ID> 
    <Title>Friday</Title> 
    <Description /> 
    <ParentID>1</ParentID> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>7</ID> 
    <Title>Saturday</Title> 
    <Description /> 
    <ParentID/> 
    <Meta /> 
    </Category> 
    <Category> 
    <ID>8</ID> 
    <Title>Sunday</Title> 
    <Description /> 
    <ParentID/> 
    <Meta /> 
    </Category> 
</Categories> 
XML; 

$xml = simplexml_load_string($str); 
$htmllist = '<ul id="p7menubar">'; 

foreach($xml->Category as $category) 
{ 
    switch($category->ID) 
    { 
     case '1': 
      $htmllist .= '<li><a class="trigger" href="#">' . $category->Title . '</a><ul>'; 
      break; 
     case '2': 
     case '3': 
     case '4': 
     case '5': 
     case '6': 
      $htmllist .= '<li><a href="#">' . $category->Title . '</a></li>'; 
      break; 
     case '7': 
      $htmllist .= '</ul><li><a href="index.htm">' . $category->Title . '</a></li>'; 
      break; 
     case '8': 
      $htmllist .= '</ul><li><a href="index.htm">' . $category->Title . '</a></li></ul>'; 
      break; 
    } 
} 

echo $htmllist; 

?> 

Quelques conseils d'optimisation:

  • Si vous pouvez vous modifier XML sou rce, vous pouvez insérer des attributs href, des classes ou toute autre variable pour un code plus propre à la fin.
  • Vous pouvez même vouloir créer des noeuds XML imbriqués de sorte que votre ul presque peut avoir lieu dans le fichier XML se
1

j'ai décidé de bash sur ce code pour les 20 dernières minutes. Vous avez besoin de deux instances de la liste, sinon vous modifiez l'index au milieu de l'itération. Mon conseil est la partie supérieure:

if (file_exists('cats.xml')) { 
    $xml = simplexml_load_file('cats.xml'); 
    $categories = simplexml_load_file('cats.xml'); 
} else { 
    exit('Failed to open cats.xml.'); 
} 
echo "<ul>"; 
foreach($categories as $category) { 
    if (!(int)$category->ParentID > 0){ 
     // if the parentid is not set this is a root element and we want to print it and 
     // it's children. 
     categorylist($category, $xml); 
    } 
} 
echo "</ul>"; 
function categorylist($current, $list){ 
    // so echo the item list and link opener, but not the closer 
    echo "<li><a href='index.php?Cat=$current->ID'>$current->Title</a>"; 
    // we need to count the number of children 
    $count = 0; 
    foreach($list as $item){ 
      // just iterate through the list for a match 
     if ((int)$item->ParentID == (int)$current->ID){ 
      if($count == 0){ 
          // if its the first match open the new child list tag 
       echo "<ul>"; 
      } 
        // print the child link and item and iterate the counter 
      echo "<li><a href=index.php?Cat=$item->ID>$item->Title</a></li>"; 
      $count = $count + 1; 
     } 
    } 
    if($count > 0){ 
      // if their were children print the close of the list 
     echo "</ul>"; 
    } 
    // now close the list item. 
    echo "</li>"; 
} 

cela devient la sortie que vous décrivez, mais pas plus, mais il fait allusion à la méthode que vous utilisez pour créer une version récursive. Bien sûr, cats.xml contient votre contenu xml ci-dessus.

1

Si vos données vont être structurées en arborescence (ce qui semble être — chaque parent a plusieurs enfants), pourquoi ne pas les stocker dans un XML comme celui-ci?

<?xml version="1.0"?> 
<Categories> 
    <Category> 
    <Title>Days</Title> 
    <Description/> 
    <Meta/> 
    <Categories> 
     <Category> 
     <Title>Monday</Title> 
     <Description/> 
     <Meta/> 
     </Category> 
     <Category> 
     <Title>Tuesday</Title> 
     <Description/> 
     <Meta/> 
     </Category> 
     <Category> 
     <Title>Wednesday</Title> 
     <Description/> 
     <Meta/> 
     </Category> 
     <Category> 
     <Title>Thursday</Title> 
     <Description/> 
     <Meta/> 
     </Category> 
     <Category> 
     <Title>Friday</Title> 
     <Description/> 
     <Meta/> 
     </Category> 
    </Categories> 
    </Category> 
    <Category> 
    <Title>Saturday</Title> 
    <Description/> 
    <Meta/> 
    </Category> 
    <Category> 
    <Title>Sunday</Title> 
    <Description/> 
    <Meta/> 
    </Category> 
</Categories> 

De cette façon, la transformation est beaucoup plus simple — vous pouvez utiliser une transformation XSLT très basique.