Ошибка DOM - ID 'someAnchor' уже определен в Entity, строка X

Если я пытаюсь загрузить документ HTML в PHP DOM, я получаю сообщение об ошибке в строках of:

Error DOMDocument::loadHTML() [domdocument.loadhtml]: ID someAnchor already defined in Entity, line: 9

Я не могу понять почему. Вот код, который загружает строку HTML в DOM.

Первый без тега привязки, а второй с ним. Второй документ выдает ошибку.

Надеюсь, вы сможете вырезать и вставить его в сценарий и запустить его, чтобы увидеть тот же результат:

<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);


$stringWithNoAnchor = <<<EOT
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body >
<h1>Hello</h1>
</body>
</html>
EOT;

$stringWithAnchor = <<<EOT
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body >
<h1>Hello</h1>
<a name="someAnchor" id="someAnchor"></a>
</body>
</html>
EOT;

class domGrabber
    {
    public $_FileErrorStr = '';

    /**
    *@desc DOM object factory does the work of loading the DOM object
    */
    public function getLoadAsDOMObj($htmlString)
        {
        $this->_FileErrorStr =''; //reset error container
        $xmlDoc = new DOMDocument();
        set_error_handler(array($this, '_FileErrorHandler')); // Warnings and errors are suppressed
        $xmlDoc->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->_FileErrorStr === null)
            {
            $this->_FileErrorStr = $errstr;
            }
        else    {
            $this->_FileErrorStr .= (PHP_EOL . $errstr);
            }
        }
    }

$domGrabber = new  domGrabber();
$xmlDoc = $domGrabber->getLoadAsDOMObj($stringWithNoAnchor );

echo 'PHP Version: '. phpversion() .'<br />'."\n";

echo '<pre>';
print $xmlDoc->saveXML();
echo '</pre>'."\n";
if ($domGrabber->_FileErrorStr)
    {
    echo 'Error'. $domGrabber->_FileErrorStr;
    }



$xmlDoc = $domGrabber->getLoadAsDOMObj($stringWithAnchor);
echo '<pre>';
print $xmlDoc->saveXML();
echo '</pre>'."\n";
if ($domGrabber->_FileErrorStr)
    {
    echo 'Error'. $domGrabber->_FileErrorStr;
    }

Я получаю следующее в моем представлении исходного кода Firefox:

PHP Version: 5.2.9<br />
<pre><?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml"><head><title>My document</title><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /></head><body>
<h1>Hello</h1>
</body></html>
</pre>
<pre><?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml"><head><title>My document</title><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /></head><body>
<h1>Hello</h1>
<a name="someAnchor" id="someAnchor"></a>

</body></html>
</pre>
Error
DOMDocument::loadHTML() [<a href='domdocument.loadhtml'>domdocument.loadhtml</a>]: ID someAnchor already defined in Entity, line: 9

Итак, почему DOM сообщает, что someAnchor уже определен?


Обновление:

Я экспериментировал с обоими

  • Вместо того, чтобы использовать loadHTML (), я использовал метод loadXML () - и это исправило его
  • Вместо того, чтобы иметь и id, и name, я использовал просто id - Attribute, и это исправило его. 12102] См. Сценарий сравнения здесь для завершения:

    <?php
    ini_set('display_errors', 1);
    error_reporting(E_ALL);
    
    
    $stringWithNoAnchor = <<<EOT
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>My document</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    </head>
    <body >
    <p>stringWithNoAnchor</p>
    </body>
    </html>
    EOT;
    
    $stringWithAnchor = <<<EOT
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>My document</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    </head>
    <body >
    <p>stringWithAnchor</p>
    <a  name="someAnchor" id="someAnchor" ></a>
    </body>
    </html>
    EOT;
    
    $stringWithAnchorButOnlyIdAtt = <<<EOT
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>My document</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    </head>
    <body >
    <p>stringWithAnchorButOnlyIdAtt</p>
    <a id="someAnchor"></a>
    </body>
    </html>
    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->_FileErrorStr ='';
    
            $xmlDoc = new DOMDocument();
            set_error_handler(array($this, '_FileErrorHandler')); // Warnings and errors are suppressed
    
    
            if ($this->useHTMLMethod)
                {
                $xmlDoc->loadHTML($htmlString);
                }
            else    {
                $xmlDoc->loadXML($htmlString);
                }
    
    
            restore_error_handler();
    
            echo "<h1>";
            echo ($this->useHTMLMethod) ? 'using xmlDoc->loadHTML() ' : 'using $xmlDoc->loadXML()';
            echo "</h1>";
            echo '<pre>';
            print $xmlDoc->saveXML();
            echo '</pre>'."\n";
            if ($this->_FileErrorStr)
                {
                echo 'Error'. $this->_FileErrorStr;
                }
            }
    
        /**
        *@desc public so that it can catch errors from outside this class
        */
        public function _FileErrorHandler($errno, $errstr, $errfile, $errline)
            {
            if ($this->_FileErrorStr === null)
                {
                $this->_FileErrorStr = $errstr;
                }
            else    {
                $this->_FileErrorStr .= (PHP_EOL . $errstr);
                }
            }
        }
    
    $domGrabber = new  domGrabber();
    
    echo 'PHP Version: '. phpversion() .'<br />'."\n";
    
    $domGrabber->useHTMLMethod = TRUE; //DOM->loadHTML
    $domGrabber->loadDOMObjAndWriteOut($stringWithNoAnchor);
    $domGrabber->loadDOMObjAndWriteOut($stringWithAnchor );
    $domGrabber->loadDOMObjAndWriteOut($stringWithAnchorButOnlyIdAtt);
    
    $domGrabber->useHTMLMethod = FALSE; //use DOM->loadXML
    $domGrabber->loadDOMObjAndWriteOut($stringWithNoAnchor);
    $domGrabber->loadDOMObjAndWriteOut($stringWithAnchor );
    $domGrabber->loadDOMObjAndWriteOut($stringWithAnchorButOnlyIdAtt);
    
7
задан halfer 18 May 2015 в 20:03
поделиться

1 ответ

Если вы загружаете XML-файлы (в этом случае XHTML — это XML), вам следует использовать DOMDocument::loadXML() , а не DOMDocument:: loadHTML() .

В HTML как name, так и id вводят идентификатор. Итак, вы повторяете идентификатор «someAnchor», отсюда и ошибка.

Однако валидатор W3C разрешает повторяющиеся идентификаторы в форме, которую вы показываете . Это может быть ошибка libmxl2.

В этом отчете об ошибке для libxml2 пользователь предлагает исправление, которое будет учитывать только атрибут name в качестве идентификатора:

Согласно спецификациям HTML и XHTML, только атрибут имени элемента разделяет пространство имен с атрибутами id. Для некоторых элементов можно утверждать что несколько экземпляров с одним и тем же именем не имеют смысла, но они должны тем не менее, не следует рассматривать в том же пространстве имен, что и идентификатор других элементов атрибуты.

См. http://www.zvon.org/xxl/xhtmlReference/Output/Strict/attr_name.html для всех элементы, которые принимают атрибуты имени и их семантику.

9
ответ дан 7 December 2019 в 03:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: