TL::HtmlFilter - HTMLのパースと書き換え

# NAME

TL::HtmlFilter - HTMLのパースと書き換え

# SYNOPSIS

      my $filter = $TL->newHtmlFilter(
          interest => ['form', 'textarea'],
      );
      $filter->set($html);

      while (my ($context, $elem) = $filter->next) {
          ...
      }

      print $filter->toStr;

# DESCRIPTION

## METHODS

### TL::HtmlFilter

new

        $TL->newHtmlFilter(%options)

  フィルタオブジェクトを作る。オプションは以下の通り:

  interest

    要素名、もしくは要素名にマッチする正規表現を要素とする配列。 正規表現の場合は `qr//` でコンパイルしなければならない。 マッチしなかった要素はスキップされる。省略可能。

    注意: 要素が文字列の場合は大文字小文字を無視した比較がされるが、 正規表現で同じ動作をさせるには qr/h\d/i のように i フラグを 付けなければならない。

  track

    要素名、もしくは要素名にマッチする正規表現を要素とする配列。 正規表現の場合は `qr//` でコンパイルしなければならない。 マッチした要素は、その子要素内で取り出す事が出来る。省略可能。

    注意: 要素が文字列の場合は大文字小文字を無視した比較がされるが、 正規表現で同じ動作をさせるには qr/h\d/i のように i フラグを 付けなければならない。

  filter_text

    真なら要素内のテキスト部分も検出する。

  filter_comment

    真ならコメントも検出する。

  my_bootstrap

    内部メソッド

set

        $filter->set($html)

  パース対象のHTMLを設定する。

toStr

        my $html = $filter->toStr()

  フィルタリング結果のHTMLを文字列で返す。

next

        my ($context, $elem) = $filter->next;

  次の要素/テキスト/コメントを取り出す。 戻り値は二つで、最初の項目は "TL::HtmlFilter::Context" 、 次の項目は "TL::HtmlFilter::ElementBase" のオブジェクトである。

### TL::HtmlFilter::Context

newElement

        $context->newElement($name)

  指定された要素名を持つ "TL::HtmlFilter::Element" を作成して返す。

newText

        $context->newText($str)

  指定された内容を持つ "TL::HtmlFilter::Text" を作成して返す。

newComment

        $context->newComment($str)

  指定された内容を持つ "TL::HtmlFilter::Comment" を作成して返す。

in

        my $element = $context->in($name)

  現在の文脈が、指定された名前を持つ要素の中であれば、その要素を返す。 要素の中であるとは、現在の要素がその要素の子孫であるか、その要素内に 含まれるテキストやコメントである場合を云う。

add

        $context->add($elem)
        $context->add('text')

  新たな要素を、現在の要素の直後に挿入する。 引数は文字列または "TL::HtmlFilter::ElementBase" でなければならない。 `$context->add('text')` は `$context->add($context->newText('text'))` と同値である。

delete

  現在の要素を削除する。

### TL::HtmlFilter::ElementBase

このクラスは以下のクラスの親クラスである。

"TL::HtmlFilter::Element"
"TL::HtmlFilter::Text"
"TL::HtmlFilter::Comment"

isElement

        $elem->isElement()

  "TL::HtmlFilter::Element" のインスタンスであれば1を返す。

isText

  "TL::HtmlFilter::Text" のインスタンスであれば1を返す。

isComment

  "TL::HtmlFilter::Comment" のインスタンスであれば1を返す。

### TL::HtmlFilter::Element

name

        $elem->name()
        $elem->name($new_name)

  要素名を返す。引数が与えられた場合は要素名を変更する。 元の要素名が大文字であった場合には、この関数も大文字で返す事に注意。

parse

        $elem->parse('<foo bar="111" baz="222">')

  文字列で渡されたHTML要素をパースして、要素名と属性を置き換える。

attr

        $elem->attr($key)
        $elem->attr($key => $value)

  指定された属性名を持つ属性があれば、その値を返す。 引数が二つ指定された場合は、指定された属性値を書換える。 属性名の大文字小文字は保存されるが、検索時には区別されない。

attrList

        my @attrs = $elem->attrList()

  存在する全ての属性名を配列で返す。

end

        $elem->end()
        $elem->end('checked')

  属性値の存在しない属性名があれば返す。値が指定された場合は、その値を設定する。 input要素の"checked"等、またXHTMLの空要素 "/" が該当する。

tail

  end の別名。

toStr

        $str = $elem->toStr

  要素を文字列化する。この要素が文字列をパースして作られたものである時は、 パースした文字列の属性の順序が保存される。

### TL::HtmlFilter::Text

str

        $elem->str()
        $elem->str($string)

  テキストの内容を返す。値が指定された場合は、内容を置き換える。

toStr

  テキストの内容を返す。

### TL::HtmlFilter::Comment

str

        $elem->str()
        $elem->str($string)

  コメントの内容を返す。"<!-- -->"は付かない。 値が指定された場合は内容を置き換える。文字列が"--"を含んでいてはならない。

toStr

  "<!-- -->"を付けた内容を返す。

## サンプル

### コード

     # フィルタの準備
     my $filt = $TL->newHtmlFilter(
         # a, form, b要素のみ検出する。bは閉じタグも見る。それ以外は見ない。
         interest => [qw(^a$ form /?b)], # 正規表現の配列

         # select, option要素の場合は、その要素内で$context->in('select')を呼ぶ事で
         # TL::HtmlFilter::Elementのオブジェクトを得る事が出来る。
         track => [qw(select option)], # 正規表現の配列

         # 真ならタグ以外の部分も見る。コメントは別扱い。
         filter_text => 1,

         # 真ならコメントの部分も見る。
         filter_comment => 1,
        );

     # フィルタに通すHTMLを設定
     $filt->set(q{
     <form>
       <select>
         <a href="http://example.com/" target="_new">foo</a>
         <b>bold</b>
         <option></option>
       </select>
       <!-- this is a comment -->
     </form>});

     while (my ($context, $elem) = $filt->next) {
         if ($elem->isElement) {
             if ($elem->name eq 'a') {
                 # <select>要素の中なら、href属性を書換える
                 if ($context->in('select')) {
                     $elem->attr(href => 'http://ymir.jp/');
                 }
             }
             elsif ($elem->name eq 'form') {
                 # form要素の開始直後に別の要素を挿入
                 my $hidden = $context->newElement('input');
                 $hidden->attr(name => 'foo');
                 $hidden->attr(type => 'hidden');
                 $hidden->end('/'); # <input name="foo" type="hidden" />を作る

                 $context->add($hidden);
             }
             elsif ($elem->name eq 'b' or $elem->name eq '/b') {
                 # b要素は消す。
                 $context->delete;
             }
         }
         elsif ($elem->isText) {
             if ($context->in('option')) {
                 # <option>の中なら書換える
                 $context->delete;
                 $context->add('AAAAA'); # テキストを追加。
                 # $context->add($context->newText('AAAAA')); と等価。

                 # 同時にこのテキストの親であるoption要素に属性を追加する。
                 $context->in('option')->attr(foo => 'bar');
             }
         }
         elsif ($elem->isComment) {
             # コメントは全て消す。
             $context->delete;
         }
     }

     # フィルタリング結果を出力する
     print $filt->toStr, "\n";

### 実行結果

     <form><input name="foo" type="hidden" />
       <select>
         <a href="http://ymir.jp/" target="_new">foo</a>
         bold
         <option foo="bar">AAAAA</option>
       </select>

     </form>

# SEE ALSO

TL

TL::HtmlFilter - HTMLのパースと書き換え

# INDEX

- "TL::HtmlFilter::Comment"
- "TL::HtmlFilter::Element"
- "TL::HtmlFilter::Text"
- DESCRIPTION
- METHODS
- NAME
- SEE ALSO
- SYNOPSIS
- TL::HtmlFilter
- TL::HtmlFilter::Comment
- TL::HtmlFilter::Context
- TL::HtmlFilter::Element
- TL::HtmlFilter::ElementBase
- TL::HtmlFilter::Text
- add
- attr
- attrList
- delete
- end
- filter_comment
- filter_text
- in
- interest
- isComment
- isElement
- isText
- my_bootstrap
- name
- new
- newComment
- newElement
- newText
- next
- parse
- set
- str
- tail
- toStr
- track
- コード
- サンプル
- 実行結果

TL::HtmlFilter - HTMLのパースと書き換え