gpt4 book ai didi

php - DOM 错误 - ID 'someAnchor' 已在实体中定义,第 X 行

转载 作者:可可西里 更新时间:2023-11-01 12:51:57 26 4
gpt4 key购买 nike

如果我尝试将 HTML 文档加载到 PHP DOM 中,我会收到如下错误:

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

我不知道为什么。下面是一些将 HTML 字符串加载到 DOM 中的代码。

第一个不包含 anchor 标记,第二个包含 anchor 标记。第二个文档产生错误。

希望您能够将其剪切并粘贴到脚本中并运行它以查看相同的输出:

<?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 源代码 View 中:

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 - 属性并修复了它。

为了完成,请在此处查看比较脚本:

<?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);

最佳答案

如果您正在加载 XML 文件(在这种情况下,XHTML 就是 XML),那么您应该使用 DOMDocument::loadXML() , 不是 DOMDocument::loadHTML() .

在 HTML 中,nameid介绍一个ID。所以你在重复 id“someAnchor”,因此是错误的。

但是,W3C 验证器允许在您显示的表单中重复 ID <a id="someAnchor" name="someAnchor"></a> .这可能是 libmxl2 的一个错误。

在此bug report对于 libxml2,用户提出了一个只考虑 name 的补丁属性作为 ID:

According to the HTML and XHTML specs, only the a element's name attribute shares name space with id attributes. For some of the elements it can be argued that multiple instances with the same name don't make sense, but they should nevertheless not be considered in the same namespace as other elements' id attributes.

See http://www.zvon.org/xxl/xhtmlReference/Output/Strict/attr_name.html for all the elements that take name attributes and their semantics.

关于php - DOM 错误 - ID 'someAnchor' 已在实体中定义,第 X 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3614586/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com