我有一个多级列表,示例如下:
<ul>
<li>Test column 01
<ul>
<li>Test column 02
<ul>
<li>Test column 03
<ul>
<li>Test column 04
<ul>
<li>Test column 05</li>
<li>Test column 05</li>
<li>Test column 05</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
我想运行一些php代码,输出列表为csv文件,格式如下:
Test column 01
,Test column 02
,,Test column 03
,,,Test column 04
,,,,Test column 05
,,,,Test column 05
,,,,Test column 05
基本上,我希望能够运行一个html列表,(无限数量的水平),通过一些php代码,并输出一个csv文件,可以在excel中打开,保留列中的列表水平。
如果我能找到一些方法添加类到每个列表项目,根据它的级别,所以第一个级别的列表项目得到一个级别1的类,第二级,一个级别2的类,等等,那么它应该是相当直接地找到并替换其余的。
这将适用于您的示例HTML:
$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
$dom->loadHTML($html);
foreach ($dom->getElementsByTagName('li') as $li) { // #1
printf(
'%s%s%s',
str_repeat(',', get_depth($li)), // #2
trim($li->childNodes->item(0)->nodeValue), // #3
PHP_EOL
);
}
function get_depth(DOMElement $element)
{
$depth = -1;
while ( // #4
$element->parentNode->tagName === 'li' ||
$element->parentNode->tagName === 'ul'
) {
if ($element->parentNode->tagName === 'ul') { // #5
$depth++;
}
$element = $element->parentNode;
}
return $depth;
}
你可以在这里看到演示。
标记说明:
- 我们获取标记中的所有LI元素,而不管它们的位置。如果您只想获取一个特定的UL块,那么就从包含起始UL元素的DOMElement中使用getElementsByTagName。我把它留给你去想怎么做。
- 每个计算深度加一个逗号。深度等于当前LI元素上面的UL元素的数量
- 我们只获取LI元素的第一个子节点,假设它是您想要的文本节点。如果实际标记包含的不仅仅是文本节点和潜在的UL元素,则需要对其进行调整,使其只包含所需的文本内容。我们正在修剪文本结果,以删除当LI元素中有子UL元素时将出现的换行符。 为了获得深度,我们遍历DOM树,直到不再有LI或UL元素。
- 由于我们希望在初始LI之上的每个UL元素都有一个逗号,所以只有当parentNode是UL元素 时,我们才在$depth上添加+1