2017-02-21 97 views
2

我使用Symfony DOM Crawler讀取並保存包含模板的HTML文檔。但是模板中缺少結束的HTML標籤。這裏有一個例子:Symfony Dom Crawler在模板中缺少結束標記

<?php 

$htmlString = <<<'HTML' 
<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Title</title> 
</head> 
<body> 
<h1>Title</h1> 
<script id="my-template" type="text/template"> 
    <div>{{ Name }}</div> 
</script> 
</body> 
HTML; 

$crawler = new Crawler($htmlString); 

$output = join(
    $crawler->filterXPath('//body')->each(
     function (Crawler $node, $i) use ($htmlString) { 
      return $node->html(); 
     } 
    ) 
); 

我希望是這樣的:

<h1>Title</h1> 
<script id="my-template" type="text/template"> 
    <p>Hello</p> 
    <div>{{ Name }}</div> 
</script> 

,但我得到:

<h1>Title</h1> 
<script id="my-template" type="text/template"> 
    <p>Hello 
    <div>{{ Name }} 
</script> 

你有任何想法,爲什麼是DOM履帶省略閉幕標籤?

回答

2

我做了一些調試和隔離這個問題與下面的代碼(如履帶採用DOMElement對象):

$htmlString = <<<'HTML' 
    <script id="my-template" type="text/template"> 
     <div> Name </div>;  
    </script> 
HTML; 

$el = new \DOMDocument(); 
libxml_use_internal_errors(true); 
$el->loadHTML($htmlString); 
echo $el->saveHTML($el); 

。OUPUTS(文檔類型,htmlhead自動添加,但它並不重要):

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
<html><head><script id="my-template" type="text/template"> 
      <div> Name ;   
     </script></head></html> 

正如您所看到的,它給出了與script內關閉標記類似的問題。

如果您註釋掉libxml_use_internal_errors(true);,那麼你會得到一個錯誤:

DOMDocument::loadHTML(): Unexpected end tag : div in Entity, line: 2

我也做了一些研究有關此錯誤,並發現這是很老的bug libxml2庫,並沒有嚴格的PHP問題:

https://bugs.php.net/bug.php?id=52012

我得到關於PHP 7.0.6這個問題,所以我想它仍然不是固定的。

一般來說,它看起來像是由libxml庫解析標籤,因此您不得不使用Crawler,或者不要將HTML模板放置在腳本標籤中。解決方案可能因您嘗試實現的目標而異。