非整形HTMLからsimplexmlの生成
Tidyを使う方法はもちろんですが、他にも選択肢はあります。
Tidy使えないときのためにHTMLParserとXML_HTMLSAX3を使う方法を以下においておきます。
用意するもの
- HTMLParser-1.2.1
- XML_HTMLSAX3(HTMLParserに付属しているはずです)
下ごしらえ
HTMLCleaner.class.php
<?php //------------------------------------- // 未整形HTMLの解析 class HTMLCleaner { protected $htmlparser_lib_dir; protected $parser; //------------------------------------- // コンストラクタ public function __construct () { $this->htmlparser_dir =dirname(__FILE__).'/HTMLParser-1.2.1'; define("XML_HTMLSAX3",$this->htmlparser_dir.'/XML/'); require_once($this->htmlparser_dir.'/HTMLParser.class.php'); $this->parser =new HTMLParser; $this->parser->setRuleFile($this->htmlparser_dir.'/xhtml1-transitional_dtd.inc.php'); $this->parser->setRoot('html',array("lang" =>"ja")); } //------------------------------------- // HTMLの解析修正 public function clean_html ($html) { $parser =clone $this->parser; $parser->parse($html); return $parser->dump(); } //------------------------------------- // HTMLからsimplexmlを得る public function get_simplexml ($html) { // UTF-8の文字セット正規化 $utf_escape_patterns =array( // 波ダッシュを全角チルダ(〜)へ変換 '/\xE3\x80\x9C/' =>"\xEF\xBD\x9E", // 全角マイナス記号(−)の変換 '/\xE2\x88\x92/' =>"\xEF\xBC\x8D", // 双柱・平行記号(‖)の変換 '/\xE2\x80\x96/' =>"\xE2\x88\xA5", // セント記号(¢)の変換 '/\xC2\xA2/' =>"\xEF\xBF\xA0", // ポンド記号(£)の変換 '/\xC2\xA3/' =>"\xEF\xBF\xA1", // 否定記号(¬)の変換 '/\xC2\xAC/' =>"\xEF\xBF\xA2", ); $html =preg_replace( array_keys($utf_escape_patterns), array_values($utf_escape_patterns), $html); $html =preg_replace('!<\!--.*?-->!s','',$html); $html =preg_replace( '!<\!\[CDATA\s*\[(.*?)\]\]>!se', 'htmlspecialchars("$1");', $html); $html =str_replace(' ',' ',$html); $html =$this->clean_html($html); $xml =simplexml_load_string($html,null,LIBXML_COMPACT); if ( ! $xml instanceof SimpleXMLElement) { print htmlspecialchars($html); } return $xml; } }