【问题标题】:DOMDocument saveHTML is not returning correct HTML Standards for "IMG", "INPUT"DOMDocument saveHTML 没有为“IMG”、“INPUT”返回正确的 HTML 标准
【发布时间】:2017-04-07 05:53:09
【问题描述】:

我是 PHP 库 phpQuery 内容解析器的忠实粉丝(因为它很像 jQuery,同时使用 PHP DOMDocument 提取标记)但我注意到了一个错误快速关闭事件<img />而不是<div></div>的特定元素

我注意到这个错误也出现在 DOMDocumentphpQuery 中。

我写了一个简单的类PhpContentDocument来转储一个简单的html文档。

require_once "../phpquery_lib/phpQuery.php";
require_once "PhpContentDocument.class.php";

$sample_document = new PhpContentDocument('Sample Document');
$sample_document->addElement('text element', "<span class='text_element'>This is some Sample Text</span>");
$sample_document->addElement('image element', "<img src='png_file.png' alt='png_file' id='png_file' />");

$sample_document_string = $sample_document->get_string();

结果如你所愿......

<!DOCTYPE HTML>
<html>
<head>
<title>Sample Document</title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<body>
<span class='text_element'>This is some Sample Text</span>
<img src='png_file.png' alt='png_file' id='png_file' />
</body>
</html>

但是当使用 saveHTML 调用文档时

$php_query_document = new DOMDocument('UTF-8', '1.0');
$php_query_document->formatOutput = true;
$php_query_document->preserveWhiteSpace = true;
$php_query_document->loadHTML($sample_document_string);

$php_query_document_string = $php_query_document->saveHTML();

echo $php_query_document_string;

它返回...

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Sample Document</title>
</head>
<body>
<span class="text_element">This is some Sample Text</span>
<img src="png_file.png" alt="png_file" id="png_file">
</body>
</html>

我遇到的主要问题是,当我在元素 img#png_file 上使用 SimpleXMLElement(例如)

使用内容解析器&lt;img src="png_file.png" alt="png_file" id="png_file"&gt; 作为参数传递

$simple_doc = new SimpleXMLElement((string) $php_query_document->find('img#png_file'));

我收到以下警告和异常,即使我的原始标记可以使用 SimpleXMLElement

Warning: SimpleXMLElement::__construct(): Entity: line 1: parser error : Premature end of data in tag img line 1 in F:\xampp\htdocs\Test_Code\phpquery_test_items\index.php on line 17

Warning: SimpleXMLElement::__construct(): <img src="png_file.png" alt="png_file" id="png_file"> in F:\xampp\htdocs\Test_Code\phpquery_test_items\index.php on line 17

Warning: SimpleXMLElement::__construct(): ^ in F:\xampp\htdocs\Test_Code\phpquery_test_items\index.php on line 17

Fatal error: Uncaught exception 'Exception' with message 'String could not be parsed as XML' in F:\xampp\htdocs\Test_Code\phpquery_test_items\index.php:17 Stack trace: #0 F:\xampp\htdocs\Test_Code\phpquery_test_items\index.php(17): SimpleXMLElement->__construct('<img src="png_f...') #1 {main} thrown in F:\xampp\htdocs\Test_Code\phpquery_test_items\index.php on line 17

由于元素没有closing event

TL:DR Warning: SimpleXMLElement::__construct(): Entity: line 1: parser error : Premature end of data in tag img line 1

我该如何解决这个问题?我确实有一些想法,但最好是

  • 我想要一个解决方案,我可以使用正则表达式(我知道 ELEMENT TYPE)将/&gt; 替换为&lt;{element_type}/&gt;,反之亦然。
  • 固定saveHTMLDOMDocument 类(可能是为了继承其他功能而扩展DOMDocument 的类)。

【问题讨论】:

    标签: html simplexml domdocument w3c-validation phpquery


    【解决方案1】:

    如果您使用 DOMDocument::saveXML() 而不是 DOMDocument::saveHTML(),您将获得有效的 XML。

    如有必要,您可以去掉 xml 声明行 &lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;


    我刚刚意识到您希望 find() 方法返回正确的 XML。因此,我不确定我的上述建议是否有帮助,如果这意味着您必须更改实现该方法的类。

    也许你可以做一些有点复杂的事情,比如:

    $node = $php_query_document->find('img#png_file');
    $simple_doc = new SimpleXMLElement( $node->ownerDocument->saveXML( $node ) );
    

    这假定$nodeDOMNode 的一些实现,我怀疑它是。这样做是要求 $node-&gt;ownerDocument(包含该节点的 DOMDocument)仅将该特定节点保存为 XML。


    另一种可能性(我不一定推荐)是在解析时让SimpleXML 宽松,通过将以下libxml 选项传递给构造函数:

    $simple_doc = new SimpleXMLElement(
        (string) $php_query_document->find('img#png_file'), 
        LIBXML_NOERROR | LIBXML_ERR_NONE | LIBXML_ERR_FATAL
    );
    

    这会在解析内容时抑制 libxml 错误。 libxml 是底层 XML 解析器,由 SimpleXML 和 DOMDocument(以及其他)使用。

    【讨论】:

    • 你有正则表达式来查找单词#[0-9];例如#13; ?因为 saveXML 会插入这些随机字符引用
    • @Killrawr 我认为您没有正确使用SimpleXML,因为我相信您指的是执行var_dump() 的输出。你想用SimpleXML 达到什么目的?请用您面临的新问题编辑您的问题(或最好开始一个新问题)。如果您仍然需要正则表达式方面的帮助,还请提出一个关于正则表达式问题的全新问题。
    猜你喜欢
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2015-02-02
    • 1970-01-01
    相关资源
    最近更新 更多