2

HTML

 <h1>heading 1</h1>
 <h2>heading 2</h2>

 <h1>heading 1</h1>
 <h2>heading 2</h2>
 <h3>heading 3</h3>

Expected output

<div class="sect1">
     <h1>heading 1</h1>
<div class="sect2">
      <h2>heading 2</h2>
</div>
</div>

 <div class="sect1">
    <h1>heading 1</h1>
 <div class="sect2">
    <h2>heading 2</h2>
 <div class="sect3">
    <h3>heading 3</h3>
 </div>
 </div>
 </div>

I need to wrap h tags with div with their respective classes. How can I do it with DOM parser in php? As I don't have knowledge in DOM parser class I don't know how to start.

I tried,

$doc = new DOMDocument();
$doc->loadHTML($input); 
$div = $doc->createElement("div");
$div->setAttribute('class', 'sect1');
$h1= $doc->getElementsByTagName('h1');
$div->appendChild($h1);
??????
Learning
  • 848
  • 1
  • 9
  • 32

1 Answers1

2
        $dom = new DOMDocument();
        $dom->loadHTML('
             <h1>heading 1</h1>
             <h2>heading 2</h2>
             <h1>heading 1</h1>
             <h2>heading 2</h2>
             <h3>heading 3</h3>
        ');
        /** @var DOMElement $element */
        $elements = $dom->getElementsByTagName('*');
        $domResult = new DOMDocument();
        $need = array('h1', 'h2', 'h3'/*...*/);
        /** @var DOMElement $h */
        for ($i = 0; $i < $elements->length; $i++) {
            /** @var DOMElement $element */
            $element = $elements->item($i);
            if (in_array($element->tagName, $need)) {
                $wrap = $domResult->createElement('div');

                $wrap->setAttribute('class', 'sect1');

                $element = $domResult->createElement($element->tagName, $element->textContent);

                $wrap->appendChild($element);
                $domResult->appendChild($wrap);
            }
        }
        echo $domResult->saveHTML();
Danila Ganchar
  • 10,266
  • 13
  • 49
  • 75
  • Thanks it is fine. But, If I do the same for `h2` and `h3` as `h1`, not getting my expected output. As I'm new to `DOM parser`,everything which I try is going wrong. Can you update for `h2`and `h3` to get as my expected output which is mentioned in the post? – Learning May 29 '15 at 08:44
  • it is because you must use recursion for all possible tags. example here: http://stackoverflow.com/questions/2909849/loop-over-domdocument – Danila Ganchar May 29 '15 at 09:01
  • `h1` is the parent of `h2` then `h2` is the parent of `h3` and so on. I need output like `

    heading 1

    heading 2

    heading 3

    ` but here am am getting `

    heading 1

    heading 2

    heading 3

    `
    – Learning May 29 '15 at 09:32
  • Wrapping should be done to parent-child relationship but not to each `h` tags – Learning May 29 '15 at 09:34
  • You can create any structure using appendChild() & createElement() – Danila Ganchar May 29 '15 at 09:37
  • If `h1` has `h2` and `h3` in it then div tag should be wrapped around `h1`, `h2` and `h3` and so on. If you see my expected output in my post you will get what am expecting. – Learning May 29 '15 at 09:58
  • How to find out whether `h1` tags are followed by 'h2' or `h3`? only then the relationship will be like h1->h2->h3->h4 (if exists),therefore `div` tag of `h1` will get end in `h4` as it is `h1` ancestors – Learning May 29 '15 at 10:02
  • if ($element->tagName == 'h1') { append to main div } if ($element->tagName == 'h2') { create sub-div, create h2, append h2 to sub-div, append sub-div to main div } etc... – Danila Ganchar May 29 '15 at 10:19
  • Thank you! got it worked. Apologise for heavy comment discussion – Learning May 29 '15 at 11:01
  • No problem. Good Luck ;) – Danila Ganchar May 29 '15 at 11:02