title: DOM Error - ID 'someAnchor' already defined in Entity, line X
body: <p>If I try to load an HTML document into PHP DOM I get an error along the lines of:</p>
  
  <pre><code>Error DOMDocument::loadHTML() [domdocument.loadhtml]: ID someAnchor already defined in Entity, line: 9
  </code></pre>
  
  <p>I cannot work out why. Here is some code that loads an HTML string into DOM. </p>
  
  <p>First without containing an anchor tag and second with one. The second document produces an error.</p>
  
  <p>Hopefully you should be able to cut and paste it into a script and run it to see the same output:</p>
  
  <pre><code>&lt;?php
  ini_set('display_errors', 1);
  error_reporting(E_ALL);
  
  
  $stringWithNoAnchor = &lt;&lt;&lt;EOT
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
  &lt;title&gt;My document&lt;/title&gt;
  &lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /&gt;
  &lt;/head&gt;
  &lt;body &gt;
  &lt;h1&gt;Hello&lt;/h1&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  EOT;
  
  $stringWithAnchor = &lt;&lt;&lt;EOT
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
  &lt;title&gt;My document&lt;/title&gt;
  &lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /&gt;
  &lt;/head&gt;
  &lt;body &gt;
  &lt;h1&gt;Hello&lt;/h1&gt;
  &lt;a name="someAnchor" id="someAnchor"&gt;&lt;/a&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  EOT;
  
  class domGrabber
      {
      public $_FileErrorStr = '';
  
      /**
      *@desc DOM object factory does the work of loading the DOM object
      */
      public function getLoadAsDOMObj($htmlString)
          {
          $this-&gt;_FileErrorStr =''; //reset error container
          $xmlDoc = new DOMDocument();
          set_error_handler(array($this, '_FileErrorHandler')); // Warnings and errors are suppressed
          $xmlDoc-&gt;loadHTML($htmlString);
          restore_error_handler();
          return $xmlDoc;
          }
  
      /**
      *@desc public so that it can catch errors from outside this class
      */
      public function _FileErrorHandler($errno, $errstr, $errfile, $errline)
          {
          if ($this-&gt;_FileErrorStr === null)
              {
              $this-&gt;_FileErrorStr = $errstr;
              }
          else    {
              $this-&gt;_FileErrorStr .= (PHP_EOL . $errstr);
              }
          }
      }
  
  $domGrabber = new  domGrabber();
  $xmlDoc = $domGrabber-&gt;getLoadAsDOMObj($stringWithNoAnchor );
  
  echo 'PHP Version: '. phpversion() .'&lt;br /&gt;'."\n";
  
  echo '&lt;pre&gt;';
  print $xmlDoc-&gt;saveXML();
  echo '&lt;/pre&gt;'."\n";
  if ($domGrabber-&gt;_FileErrorStr)
      {
      echo 'Error'. $domGrabber-&gt;_FileErrorStr;
      }
  
  
  
  $xmlDoc = $domGrabber-&gt;getLoadAsDOMObj($stringWithAnchor);
  echo '&lt;pre&gt;';
  print $xmlDoc-&gt;saveXML();
  echo '&lt;/pre&gt;'."\n";
  if ($domGrabber-&gt;_FileErrorStr)
      {
      echo 'Error'. $domGrabber-&gt;_FileErrorStr;
      }
  </code></pre>
  
  <p>I get the following out put in my Firefox source code view:</p>
  
  <pre><code>PHP Version: 5.2.9&lt;br /&gt;
  &lt;pre&gt;&lt;?xml version="1.0" encoding="iso-8859-1" standalone="yes"?&gt;
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;head&gt;&lt;title&gt;My document&lt;/title&gt;&lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /&gt;&lt;/head&gt;&lt;body&gt;
  &lt;h1&gt;Hello&lt;/h1&gt;
  &lt;/body&gt;&lt;/html&gt;
  &lt;/pre&gt;
  &lt;pre&gt;&lt;?xml version="1.0" encoding="iso-8859-1" standalone="yes"?&gt;
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;head&gt;&lt;title&gt;My document&lt;/title&gt;&lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /&gt;&lt;/head&gt;&lt;body&gt;
  &lt;h1&gt;Hello&lt;/h1&gt;
  &lt;a name="someAnchor" id="someAnchor"&gt;&lt;/a&gt;
  
  &lt;/body&gt;&lt;/html&gt;
  &lt;/pre&gt;
  Error
  DOMDocument::loadHTML() [&lt;a href='domdocument.loadhtml'&gt;domdocument.loadhtml&lt;/a&gt;]: ID someAnchor already defined in Entity, line: 9
  </code></pre>
  
  <p>So, why is DOM saying that someAnchor is already defined?</p>
  
  <hr>
  
  <p>Update:</p>
  
  <p>I experimented with both </p>
  
  <ul>
  <li>Instead of using loadHTML() I used the loadXML() method - and that fixed it</li>
  <li>Instead of having both id and name I used just id - Attribute and that fixed it.</li>
  </ul>
  
  <p>See the comparison script here for the sake of completion:</p>
  
  <pre><code>&lt;?php
  ini_set('display_errors', 1);
  error_reporting(E_ALL);
  
  
  $stringWithNoAnchor = &lt;&lt;&lt;EOT
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
  &lt;title&gt;My document&lt;/title&gt;
  &lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /&gt;
  &lt;/head&gt;
  &lt;body &gt;
  &lt;p&gt;stringWithNoAnchor&lt;/p&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  EOT;
  
  $stringWithAnchor = &lt;&lt;&lt;EOT
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
  &lt;title&gt;My document&lt;/title&gt;
  &lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /&gt;
  &lt;/head&gt;
  &lt;body &gt;
  &lt;p&gt;stringWithAnchor&lt;/p&gt;
  &lt;a  name="someAnchor" id="someAnchor" &gt;&lt;/a&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  EOT;
  
  $stringWithAnchorButOnlyIdAtt = &lt;&lt;&lt;EOT
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
  &lt;title&gt;My document&lt;/title&gt;
  &lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /&gt;
  &lt;/head&gt;
  &lt;body &gt;
  &lt;p&gt;stringWithAnchorButOnlyIdAtt&lt;/p&gt;
  &lt;a id="someAnchor"&gt;&lt;/a&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  EOT;
  
  class domGrabber
      {
      public $_FileErrorStr = '';
      public $useHTMLMethod = TRUE;
  
      /**
      *@desc DOM object factory does the work of loading the DOM object
      */
      public function loadDOMObjAndWriteOut($htmlString)
          {
          $this-&gt;_FileErrorStr ='';
  
          $xmlDoc = new DOMDocument();
          set_error_handler(array($this, '_FileErrorHandler')); // Warnings and errors are suppressed
  
  
          if ($this-&gt;useHTMLMethod)
              {
              $xmlDoc-&gt;loadHTML($htmlString);
              }
          else    {
              $xmlDoc-&gt;loadXML($htmlString);
              }
  
  
          restore_error_handler();
  
          echo "&lt;h1&gt;";
          echo ($this-&gt;useHTMLMethod) ? 'using xmlDoc-&gt;loadHTML() ' : 'using $xmlDoc-&gt;loadXML()';
          echo "&lt;/h1&gt;";
          echo '&lt;pre&gt;';
          print $xmlDoc-&gt;saveXML();
          echo '&lt;/pre&gt;'."\n";
          if ($this-&gt;_FileErrorStr)
              {
              echo 'Error'. $this-&gt;_FileErrorStr;
              }
          }
  
      /**
      *@desc public so that it can catch errors from outside this class
      */
      public function _FileErrorHandler($errno, $errstr, $errfile, $errline)
          {
          if ($this-&gt;_FileErrorStr === null)
              {
              $this-&gt;_FileErrorStr = $errstr;
              }
          else    {
              $this-&gt;_FileErrorStr .= (PHP_EOL . $errstr);
              }
          }
      }
  
  $domGrabber = new  domGrabber();
  
  echo 'PHP Version: '. phpversion() .'&lt;br /&gt;'."\n";
  
  $domGrabber-&gt;useHTMLMethod = TRUE; //DOM-&gt;loadHTML
  $domGrabber-&gt;loadDOMObjAndWriteOut($stringWithNoAnchor);
  $domGrabber-&gt;loadDOMObjAndWriteOut($stringWithAnchor );
  $domGrabber-&gt;loadDOMObjAndWriteOut($stringWithAnchorButOnlyIdAtt);
  
  $domGrabber-&gt;useHTMLMethod = FALSE; //use DOM-&gt;loadXML
  $domGrabber-&gt;loadDOMObjAndWriteOut($stringWithNoAnchor);
  $domGrabber-&gt;loadDOMObjAndWriteOut($stringWithAnchor );
  $domGrabber-&gt;loadDOMObjAndWriteOut($stringWithAnchorButOnlyIdAtt);
  </code></pre>