HTML列表到CSV

时间:2013-03-01 12:33:03

标签: php excel csv html-lists

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

<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

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

如果我能找到一种方法为每个列表项添加一个类,取决于它的级别,所以第一级列表项获得level1,第二级,level2类等等,那么它应该相当简单找到并替换其余部分。

任何想法/帮助都非常感激。

1 个答案:

答案 0 :(得分: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;
}

你可以see the demo here

商标说明:

  1. 我们获取Markup中的所有LI元素,无论它们的位置如何。如果您只想获取特定的UL块,请使用包含起始UL元素的DOMElement中的getElementsByTagName。我留给你了解如何做到这一点。
  2. 我们为每个计算的深度添加一个逗号。深度等于当前LI元素之上的UL元素的数量
  3. 我们只获取LI元素的第一个子节点,假设它是您想要的文本节点。如果您的实际标记不仅包含文本节点和潜在的UL元素,则需要将其调整为仅包含所需的文本内容。我们正在修剪文本结果,以便在LI元素中存在子UL元素时删除它将具有的换行符。
  4. 获取我们遍历DOM树的深度,直到没有更多的LI或UL元素。
  5. 由于我们希望每个UL元素在初始LI之上有一个逗号,所以如果parentNode是UL元素,我们只会向$ depth添加+1