phpでhtml要素の一部を取得する

phpのDOMを使用してhtml要素(<tag>~</tag>)を取得するのが意外と難しい。
tagNameやnodeValueの取出し方は、多くの事例があるので探せば直ぐに見つかるのだが
タグそのものを表示する例はほとんど皆無に近い。

キーワードをいろいろ変えながら探した結果が次のもの。

この解決策は、DOMElement クラス内の
「User Contributed Notes」にある「63」と「15」がヒントになる。
例を見た方が手っ取り早いので、下に例を示す。

(1) サンプルとして次の sample.html を使用する

<!DOCTYPE html>
<html lang="ja">
<head>
<title>テストデータ</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h1>テストデータ</h1>
<p>&lt;table> の全要素を表示します。</p>
<table id="test" class="table">
	<tr class="tr"><th>Header1</th><th>Header2</th></tr>
	<tr><td class="td">Data1</td><td>Data2</td></td>
</table>
<div id="main">
	<p>test1</p>
	<p>test2</p>
	<a href="*">Link1</a>
	<div id="sub">
		<p>sub1</p>
		<p>sub2</p>
	</div>
</div>
</body>
</html>

(2) table内の全要素を取得する場合

<?php
header("Content-Type: text/html; charset=UTF-8");
// innerHTML形式で要素を出力する例
// 結果は「ページのソース」で確認のこと
function DOMinnerHTML(DOMNode $element) { 
    $innerHTML = ""; 
    $children  = $element->childNodes;

    foreach ($children as $child) 
    { 
        $innerHTML .= $element->ownerDocument->saveHTML($child);
    }

    return $innerHTML; 
}

$dom= new DOMDocument(); 
$html = "sample.html";
@$dom->loadHTMLFile($html);
// xpathを使用しない場合
//$domTables = $dom->getElementsByTagName("table"); 
$xpath = new DOMXpath($dom);
$domTables = $xpath->query("//table");
if (!is_null($domTables)) {
	// Iterate over DOMNodeList (Implements Traversable)
	foreach ($domTables as $table){ 
		echo DOMinnerHTML($table); 
	} 
}else{
	echo "一致するデータがありません!";
}
?>

(3)id=”main”であるdiv要素内の全要素を取得する

<?php
header("Content-Type: text/html; charset=UTF-8");
// innerHTML形式で要素を出力する例
// 結果は「ページのソース」で確認のこと
function DOMinnerHTML(DOMNode $element) { 
    $innerHTML = ""; 
    $children  = $element->childNodes;

    foreach ($children as $child) 
    { 
        $innerHTML .= $element->ownerDocument->saveHTML($child);
    }

    return $innerHTML; 
}

$dom= new DOMDocument(); 
$html = "sample.html";
@$dom->loadHTMLFile($html);
$xpath = new DOMXpath($dom);
$domTables = $xpath->query("//div[@id='main']");
if (!is_null($domTables)) {
	// Iterate over DOMNodeList (Implements Traversable)
	foreach ($domTables as $table){ 
		echo DOMinnerHTML($table); 
	} 
}else{
	echo "一致するデータがありません!";
}
?>

(注)結果は、ブラウザの画面を右クリックして、「ページのソースを表示」(Firefoxの場合)で確認してください。