tetsunosukeのnotebook

tetsunosukeのメモです

やっとできたよGoogleNotebookのハック

これでとりあえずHTML解析の「キホン」がなんとなくわかった気がする。

メイン
main.php

<?php
ini_set('include_path', ini_get('include_path') . ";./lib");
require_once 'XML/XML_HTMLSax.php';
require_once 'MyHTMLParser.php';
require_once 'HTTP/Request.php';
define('PUBLICNOTE_URL','http://www.google.com/notebook/public/06371770224987391924/BDTbFIgoQ8pbC47Mh');

// ファイル取得
$req =& new HTTP_Request(PUBLICNOTE_URL);
if(!PEAR::isError($req->sendRequest())){
    $contents = $req->getResponseBody();
}


// Parsing
$handler = new MyHTMLParser();

$parser =& new XML_HTMLSax();
$parser->set_object($handler);
$parser->set_option('XML_OPTION_TRIM_DATA_NODES');

// handlers
$parser->set_element_handler('openHandler', 'closeHandler');
$parser->set_data_handler('dataHandler');
$parser->parse($contents);
?>

MyHTMLParser.php

<?php
class MyHTMLParser{
    var $elements;
    function MyHTMLParser()
    {
        $this->elements = array();
    }


    /** 
     * 要素を開いた段階でその情報(要素の属性と名前)を
     * 連想配列に突っ込む。属性の中で利用するのはname, id, classのみ。
     */
    function openHandler( &$parser, $name, $attrs )
    {
        switch($name){
            /** 閉じない要素とpを無視 */
            case "br":
            case "img":
            case "link":
            case "p":
                break;
            default:
                $tmpArray = array();

            foreach($attrs as $key => $value){
                switch($key){
                    case "id":
                    case "class":
                    case "name":
                        $tmpArray[] = array($key => $value);
                        break;
                    default:
                        break;
                }
            } 
        
        
            if(count($tmpArray) > 0){
                array_push($this->elements, array($name=>$tmpArray));
            } else {
                array_push($this->elements, $name);
            }
        }
    }

    /** 
     * 要素を閉じるときにその直前の内容を保持している配列から
     * 処理済である末尾の要素を削除する
     */
    function closeHandler( &$parser, $name )
    {
        /** 閉じるPは開くPを無視したので無視*/
        if($name != 'p'){
            array_pop($this->elements);
        }
    }


    /**
     * テキストノードの解釈。
     * 自分自身が現在どこを処理対象としているかで各関数の
     * 判定を行い、その判定が正しければ内容を出力
     */
    function dataHandler( &$parser, $data )
    {
        if($this->_getTitle()){
            print "gettitle =====" . $data . "=====\n";
        }
    }



    /**
     * 二つの連想配列がデータとして等しいかどうかを返す
     * @todo 多分serializeしたものを小文字で比較した方が良い
     */
    function _isValidArray($inputArray, $expectedArray)
    {
        return strtolower(serialize($inputArray)) == strtolower(serialize($expectedArray));
    }
    
    /**
     * HTML中からNoteのタイトル部分を抜き出す
     */
    function _getTitle()
    {
        $expectedArray = 
              array(
                  'html',
                  'body',               
                  array('div' => array(array('id' => 'pubContent'))),
                  array('table' => array(array('class' => 'PubNote'))),
                  'tr',
                  'td'
              );
        
        return $this->_isValidArray($this->elements, $expectedArray);
    }
}
?>