6

I'm really struggling to get my head around DOMDocument parsing. I'm trying to solve the following problem. Given the following HTML

<h1>Title</h1>
<p>Some Content</p>
<p>Some More Content</p>
<p>Other Content</p>
<p>Last Bit of Content</p>

I want to add in a div with something else after the second paragraph tag. Essentially the outcome needs to be something like the following

<h1>Title</h1>
<p>Some Content</p>
<p>Some More Content</p>
<div>Something different</div> <!-- new tag -->
<p>Other Content</p>
<p>Last Bit of Content</p>

Having looked at a few post on here I'm now getting bored of scratching my head now.

5
  • 2
    Thanks for our help with what? Reading your post? What question did you have? Did you want us to write the code? Commented Oct 11, 2016 at 18:39
  • Pointing in the right direction would help being so DOMDocument is new to me. Commented Oct 11, 2016 at 18:41
  • Is html plain? Are you using a js library like jquery? Commented Oct 11, 2016 at 18:44
  • Is the right direction "how to use DomDocument"? The right direction is to try. If what you try fails, bring the bad code back to us and let us see where you've gone astray. Commented Oct 11, 2016 at 18:44
  • 1
    php.net/manual/en/domnode.appendchild.php Commented Oct 11, 2016 at 18:46

2 Answers 2

8

You need to use DOMDocument class to parsing string to html. After parsing html, select third p element and use DOMNode::insertBefore to insert new element after it.

$doc = new DOMDocument();
$doc->loadHTML($html);
// find 3th p tag
$p = $doc->getElementsByTagName("p")->item(2);
// create new div tag
$div = $doc->createElement("div", "Something different"); 
// insert created element after 3th p
$p->parentNode->insertBefore($div, $p); 
$html = $doc->saveHTML();
Sign up to request clarification or add additional context in comments.

2 Comments

how to add tag attribute in create element
@mehul Using setAttribute() method. Check this
1

In complement to @Mohammad answer (that is perfectly correct), if you want to find precisely the second p tag after an h1 tag and at the same level, you can use the XPath query //h1/following-sibling::p[2]. Example:

$html = <<<'EOD'
<h1>Title</h1>
<p>Some Content</p>
<p>Some More Content</p>
<p>Other Content</p>
<p>Last Bit of Content</p>
EOD;

libxml_use_internal_errors(true);

$dom = new DOMDocument;
$dom->loadHTML('<div>' . $html . '</div>', LIBXML_HTML_NOIMPLIED);

libxml_clear_errors();

$xp = new DOMXPath($dom);

$targetNode = $xp->query('//h1/following-sibling::p[2]');

if ($targetNode->length) {
    $targetNode = $targetNode->item(0);
    $newNode = $dom->createElement('div', 'something different');
    $targetNode->parentNode->insertBefore($newNode, $targetNode->nextSibling);
    $targetNode->parentNode->insertBefore($dom->createTextNode("\n"), $targetNode->nextSibling);
}

$result = '';
foreach ($dom->documentElement->childNodes as $childNode) {
    $result .= $dom->saveHTML($childNode);
}
echo $result;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.