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番目のレベル、レベル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. 計算された深さごとに1つのコンマを追加します。深さは、現在のLI要素より上のUL要素の量に等しい
  3. 必要なテキストノードであると想定して、LI要素の最初の子ノードのみをフェッチします。実際のマークアップにテキストノードと潜在的なUL要素以外のものが含まれている場合は、必要なテキストコンテンツのみが含まれるようにこれを調整する必要があります。LI要素に子UL要素がある場合に含まれる改行を削除するために、テキスト結果をトリミングしています。
  4. 深さを取得するために、LIまたはUL要素がなくなるまでDOMツリーをトラバースします。
  5. 最初のLIの上にUL要素ごとに1つのコンマが必要なので、parentNodeがUL要素の場合、$depthに+1を追加するだけです。
于 2013-03-01T13:35:01.370 に答える