【问题标题】:Get menu array from HTML string using PHP DOM document使用 PHP DOM 文档从 HTML 字符串中获取菜单数组
【发布时间】:2020-04-29 21:15:19
【问题描述】:

我有以下代码:

$string = '<html><head></head><body><ul id="mainmenu">
  <li id="1"><a href="1"> main menu 1 </a> </li>
  <li id="2"> <a href="2"> main menu 2 </a> </li>
    <ul class="sub-menu">
      <li id="3"> <a href="3"> Sub menu 2 </a> </li>
      <li id="4"> <a href="4"> Sub menu 2.1 </a> </li>
    </ul>
  </li>
</ul></body></html>';
$dom = new DOMDocument;
$dom->loadHTML($string);

现在我想要一个数组作为输出,其中包含使用 PHP DOM 文档的 href、value 和 submenu 字段以及各自的值。

类似这样的:

Array
(
    [0] => Array
        (
            [href] => 1
            [name] => Main menu 1
            [sub] => Array
                (
                )

        )

    [1] => Array
        (
            [href] => 2
            [name] => main menu 2
            [sub] => Array
                (
                   [0] => Array
                    (
                       [href] => 3
                       [name] => sub menu 2
                       [sub] => Array
                             (
                              )

                    )

                   [1] => Array
                       (
                         [href] => 4
                          [name] => sub main menu 2.1
                         [sub] => Array
                             (

                             )

                   )
                )

        )
)

我能够将所有菜单项作为主菜单,并将所有子菜单数组设为空。如何通过解析 HTML 字符串来实现这一点?

【问题讨论】:

标签: php html parsing dom domdocument


【解决方案1】:

假设您只有两个级别,此代码使用 XPath 查找每个菜单的开始,然后循环通过 &lt;li&gt; 元素。它对子菜单做类似的事情,使用当前主菜单作为起点,只使用内容(使用descendant:: 限制搜索的节点)....

(我不得不更改 HTML,因为在 &lt;li id="2"&gt; &lt;a href="2"&gt; main menu 2 &lt;/a&gt; &lt;/li&gt; 中有一个额外的 &lt;li&gt;

$string = '<html><head></head><body><ul id="mainmenu">
  <li id="1"><a href="1"> main menu 1 </a> </li>
  <li id="2"> <a href="2"> main menu 2 </a>
    <ul class="sub-menu">
      <li id="3"> <a href="3"> Sub menu 2 </a> </li>
      <li id="4"> <a href="4"> Sub menu 2.1 </a> </li>
    </ul>
  </li>
</ul></body></html>';
$dom = new DOMDocument;
$dom->loadHTML($string);
$xp = new DOMXPath($dom);
$menus = [];

$mainMenus = $xp->query('//ul[@id="mainmenu"]/li');
foreach ( $mainMenus as $menu )  {
    $a = $menu->getElementsByTagName("a")[0];
    $newMenu = [ "href" => $a->getAttribute("href"),
        "name" => $a->textContent
    ];

    $subMenus = $xp->query('descendant::ul[@class="sub-menu"]/li', $menu);
    foreach ( $subMenus as $menu1 )  {
        $a = $menu1->getElementsByTagName("a")[0];

        $newMenu['sub'][] = [ "href" => $a->getAttribute("href"),
            "name" => $a->textContent
        ];
    }
    $menus[] = $newMenu;
}

如果您有一个可能的 ID 列表,那么您可以使用 XPath 来查找其中的任何一个。

//ul[@id="mainmenu" or @id="menu-main" or @id="menu-menu1"]/li

如果需要,您可以从数组动态构建它...

$menu_ids_arr = array('mainmenu', 'menu-main', 'menu-menu1');
$query = '//ul[';
foreach ( $menu_ids_arr as $id )    {
    $query .= '@id="'.$id.'" or ';
}
$query = substr($query, 0, -4).']/li';
$mainMenus = $xp->query($query);

【讨论】:

  • 现在我正在寻找的不是硬编码 ul id(在本例中为 mainmenu),我有一个预定义的 id 数组,并且只需要解析其 id 与大批。例如 - $menu_ids_arr = array('mainmenu', 'menu-main', 'menu-menu1');仅当 ul 的 id 是上述 3 之一时才应该解析 ul(在数组中给出)
  • 我为此添加了更多解释。
猜你喜欢
  • 1970-01-01
  • 2021-05-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-20
  • 2010-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多