如何将XML转换为分层HTML菜单?

时间:2010-07-06 06:33:01

标签: php xml

我一直在尝试使用PHP构建一个子/父导航一段时间(我来自.net背景),我无法接近所需的结果。我正在使用SimpleXML成功地从XML文件加载我的数据,但我正在尝试找出如何将其映射到数组或变量中以便我可以将其写出来。

  <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>";

所以我想要的输出是这样的:

<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>

3 个答案:

答案 0 :(得分:1)

我决定在最后20分钟内使用此代码。您需要列表的两个实例,否则您将更改索引中间迭代。我的建议是最重要的领域:

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>";
}

这会获得您描述的输出,但不会更多,但它暗示了您将用于创建递归版本的方法。当然cats.xml包含上面的xml内容。

答案 1 :(得分:1)

如果你的数据是树形的(似乎是 - 每个父母都有多个孩子),为什么不将它们存储在这样的XML中呢?

<?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>

这种方式转换要简单得多 - 您可以使用非常基本的XSLT转换。

答案 2 :(得分:0)

当然需要进行大量优化,但这就是诀窍

$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;

?>

一些优化提示:

  • 如果您可以修改XML源代码,则可以在最后插入href属性,类或任何其他变量以获得更清晰的代码。
  • 您甚至可以创建嵌套的XML节点,这样您的ul几乎可以在XML本身中进行