使用 PHP DOM 文档从 HTML 字符串获取菜单数组
Get menu array from HTML string using PHP DOM document
我有以下代码:
$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、值和子菜单字段。
像这样:
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 字符串来实现?
假设您只有两个级别,此代码使用 XPath 查找每个菜单的开头,然后循环遍历 <li>
元素。它对子菜单做类似的事情,使用当前主菜单作为起点并且仅使用内容(使用 descendant::
来限制搜索的节点)......
(我不得不更改 HTML,因为 <li id="2"> <a href="2"> main menu 2 </a> </li>
中有一个额外的 <li>
)
$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);
我有以下代码:
$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、值和子菜单字段。
像这样:
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 字符串来实现?
假设您只有两个级别,此代码使用 XPath 查找每个菜单的开头,然后循环遍历 <li>
元素。它对子菜单做类似的事情,使用当前主菜单作为起点并且仅使用内容(使用 descendant::
来限制搜索的节点)......
(我不得不更改 HTML,因为 <li id="2"> <a href="2"> main menu 2 </a> </li>
中有一个额外的 <li>
)
$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);