3

我有一个多级列表,示例如下:

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

我想运行一些将列表输出为 csv 文件的 php 代码,格式如下:

Test column 01
,Test column 02
,,Test column 03
,,,Test column 04
,,,,Test column 05
,,,,Test column 05
,,,,Test column 05

基本上,我希望能够通过一些 php 代码运行一个 html 列表(具有无限数量的级别),并输出一个可以在 excel 中打开的 csv 文件,并在列中保留列表级别。

如果我能找到某种方法为每个列表项添加一个类,具体取决于它的级别,所以第一级列表项得到一个级别 1 的类,第二级,一个级别 2 的类等,那么它应该是相当简单的找到和更换其余的。

非常感谢任何想法/帮助。

4

1 回答 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;
}

你可以在这里看到演示

标记说明:

  1. 我们获取标记中的所有 LI 元素,而不考虑它们的位置。如果您只想获取特定的 UL 块,请使用包含起始 UL 元素的 DOMElement 中的 getElementsByTagName。我把它留给你来弄清楚如何做到这一点。
  2. 我们为每个计算的深度添加一个逗号。深度等于当前 LI 元素上方的 UL 元素数量
  3. 我们只获取 LI 元素的第一个子节点,假设它是您想要的文本节点。如果您的实际标记不仅仅包含文本节点和潜在的 UL 元素,您需要调整它以仅包含您想要的文本内容。我们正在修剪文本结果以删除当 LI 元素中有子 UL 元素时它将具有的换行符。
  4. 为了获得深度,我们向上遍历 DOM 树,直到没有更多的 LI 或 UL 元素。
  5. 由于我们希望在初始 LI 之上的每个 UL 元素有一个逗号,因此我们只在 parentNode 是 UL 元素时将 +1 添加到 $depth
于 2013-03-01T13:35:01.370 回答