title: How to make HTML5 work with DOMDocument?
body: <p>I'm attempting to parse HTML code with DOMDocument, do stuff like changes to it, then assemble it back to a string which I send to the output.</p>
  
  <p>But there a few issues regarding parsing, meaning that what I send to DOMDocument does not always come back in the same form :)</p>
  
  <p>Here's a list:</p>
  
  <ol>
  <li><p>using <a href="http://php.net/manual/en/domdocument.loadhtml.php">->loadHTML</a>:</p>
  
  <ul>
  <li>formats my document regardless of the <code>preserveWhitespace</code> and <code>formatOutput</code> settings (loosing whitespaces on preformatted text)</li>
  <li>gives me errors when I have html5 tags like <code>&lt;header&gt;</code>, <code>&lt;footer&gt;</code> etc. But they can be supressed, so I can live with this.</li>
  <li>produces inconsistent markup - for example if I add a <code>&lt;link ... /&gt;</code> element (with a self-closing tag), after parsing/saveHTML the output will be <code>&lt;link .. &gt;</code></li>
  </ul></li>
  <li><p>using <a href="http://php.net/manual/en/domdocument.loadhtml.php">->loadXML</a>: </p>
  
  <ul>
  <li>encodes entities like <code>&gt;</code> from <code>&lt;style&gt;</code> or <code>&lt;script&gt;</code> tags: <code>body &gt; div</code> becomes <code>body &amp;gt; div</code></li>
  <li>all tags are closed the same way, for example <code>&lt;meta ... /&gt;</code> becomes <code>&lt;meta...&gt;&lt;/meta&gt;</code>; but this can be fixed with an regex.</li>
  </ul></li>
  </ol>
  
  <p>I didn't try HTML5lib but I'd prefer DOMDocument instead of a custom parser for performance reasons</p>
  
  <hr>
  
  <h1>Update:</h1>
  
  <p>So like the Honeymonster mentioned using CDATA fixes the main problem with loadXML.</p>
  
  <p>Is there any way I could prevent self closing of all empty HTML tags besides a certain set, without using regex?</p>
  
  <p>Right now I have:</p>
  
  <pre><code>$html = $dom-&gt;saveXML($node);
  
  $html = preg_replace_callback('#&lt;(\w+)([^&gt;]*)\s*/&gt;#s', function($matches){
  
         // ignore only these tags
         $xhtml_tags = array('br', 'hr', 'input', 'frame', 'img', 'area', 'link', 'col', 'base', 'basefont', 'param' ,'meta');
  
         // if a element that is not in the above list is empty,
         // it should close like   `&lt;element&gt;&lt;/element&gt;` (for eg. empty `&lt;title&gt;`)
         return in_array($matches[1], $xhtml_tags) ? "&lt;{$matches[1]}{$matches[2]} /&gt;" : "&lt;{$matches[1]}{$matches[2]}&gt;&lt;/{$matches[1]}&gt;";
  }, $html);
  </code></pre>
  
  <p>which works but it will also do the replacements in the CDATA content, which I don't want...</p>