2017-04-07 33 views
0

我的PHP库phpQuery内容解析器的大风扇(因为它很喜欢jQuery的,同时采用了PHP DOMDocument提取标记),但我注意到有特定元素的错误与快速关闭事件<img />,而不是<div></div>的DOMDocument saveHTML没有返回的“IMG”正确的HTML标准,“INPUT”

我已经注意到这个错误也发生在DOMDocument以及phpQuery

我写了一个简单的类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> 

我的主要问题有这种情况,就是当我使用SimpleXMLElement元素img#png_file(例如)

上使用内容分析器传递<img src="png_file.png" alt="png_file" id="png_file">作为参数

$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}/>更换/>,反之亦然。
  • DOMDocument类与saveHTML固定(也许一类扩展DOMDocument为了继承其他功能)。

回答

1

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

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


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

也许你可以做一些有点令人费解,如:

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

这预示$nodeDOMNode一些实现,我怀疑它是。它的作用是询问$node->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

您是否有正则表达式来查找单词#[0-9];例如#13; ?因为saveXML插入了这些随机字符引用 – Killrawr

+0

@Killrawr我不认为你正在使用'SimpleXML',因为你所指的是做'var_dump()'的输出,我相信。你想用'SimpleXML'实现什么?请编辑您的问题(或者最好开始一个新问题)并解决您遇到的新问题。如果您仍然需要正则表达式的帮助,请还请提出一个关于正则表达式问题的全新问题。 –