8

I am using PHP's DOM object to create HTML pages for my website. This works great for my head, however since I will be entering a lot of HTML into the body (not via DOM), I would think I would need to use DOM->createElement($bodyHTML) to add my HTML from my site to the DOM object.

However DOM->createElement seems to parse all HTML entities so my end result ended up displaying the HTML on the page and not the actual renders HTML.

I am currently using a hack to get this to work,

$body = $this->DOM
             ->createComment('DOM Glitch--><body>'.$bodyHTML."</body><!--Woot");

Which puts all my site code in a comment, which I bypass athe comment and manually add the <body> tags.

Currently this method works, but I believe there should be a more proper way of doing this. Ideally something like DOM->createElement() that will not parse any of the string.

I also tried using DOM->createDocumentFragment() However it does not like some of the string so it would error and not work (Along with take up extra CPU power to re-parse the body's HTML).

So, my question is, is there a better way of doing this other than using DOM->createComment()?

Tivie
  • 18,864
  • 5
  • 58
  • 77
lanrat
  • 4,344
  • 10
  • 35
  • 41
  • Are your sure your HTML is correct? The idea behind DOM (PHP) and similar inventions is to ensure that the markup is correct and valid and will thus reject all invalid code. – matiasf Feb 12 '10 at 21:18
  • 2
    It errors on things like "©" (inside of a

    tag)

    – lanrat Feb 12 '10 at 21:21

4 Answers4

15

You use the DOMDocumentFragment objec to insert arbitrary HTML chunks into another document.

$dom = new DOMDocument();
@$dom->loadHTML($some_html_document); // @ to suppress a bajillion parse errors

$frag = $dom->createDocumentFragment(); // create fragment
$frag->appendXML($some_other_html_snippet); // insert arbitary html into the fragment

$node = // some operations to find whatever node you want to insert the fragment into

$node->appendChild($frag); // stuff the fragment into the original tree
Marc B
  • 356,200
  • 43
  • 426
  • 500
  • The sadness with appendXML() is that your HTML must be XML compliant, which isn't always true. Case in point: $frag->appendXML('") Empty attribute values are just one of the gotchas. I ended up using the loadHTML/importNode trick shown here: https://stackoverflow.com/a/39336050 – Mike Patnode Nov 17 '18 at 01:43
1

I FOUND THE SOLUTION but it's not a pure php solution, but works very well. A little hack for everybody who lost countless hours, like me, to fix this

$dom = new DomDocument;
// main object
$object = $dom->createElement('div');

// html attribute
$attr = $dom->createAttribute('value');
// ugly html string
$attr->value = "<div>&nbsp; this is a really html string &copy;</div><i></i> with all the &copy; that XML hates!";
$object->appendChild($attr);

// jquery fix (or javascript as well)
$('div').html($(this).attr('value')); // and it works! 
$('div').removeAttr('value'); // to clean-up
Pian0_M4n
  • 2,505
  • 31
  • 35
0

loadHTML works just fine.

<?php
$dom = new DOMDocument();
$dom->loadHTML("<font color='red'>Hey there mrlanrat!</font>");
echo $dom->saveHTML();
?>

which outputs Hey there mrlanrat! in red.

or

<?php
$dom = new DOMDocument();
$bodyHTML = "here is the body, a nice body I might add";
$dom->loadHTML("<body> " . $bodyHTML . " </body>");
// this would even work as well.
// $bodyHTML = "<body>here is the body, a nice body I might add</body>";
// $dom->loadHTML($bodyHTML);
echo $dom->saveHTML();
?>

Which outputs:

here is the body, a nice body I might add and inside of your HTML source code, its wrapped inside body tags.

Anthony Forloney
  • 90,123
  • 14
  • 117
  • 115
-1

I spent a lot of time working on Anthony Forloney's answer, But I cannot seem to get the html to append to the body without it erroring.

@Mark B: I have tried doing that, but as I said in the comments, it errored on my html.

I forgot to add the below, my solution:

I decided to make my html object much simpler and to allow me to do this by not using DOM and just use strings.

lanrat
  • 4,344
  • 10
  • 35
  • 41
  • This isn't actualy an answer, because just concatenating strings is too generic. If you are not satisfied with the other ones, there is not need to post a disclaimer, just leave it as it is, with no accepted answer at all, there is no problem with that. – mikl Oct 23 '15 at 15:44