1

それぞれが特定の ID を持つ 2 つの DIV 要素を含む一連の HTML レポートを持っています。これらの要素を取り除き、全体的な概要レポート (再び HTML ファイル) にコンパイルする必要があります。

私の最初の考えでは、これは Perl スクリプトにとって理想的な仕事ですが、社内には最新の Perl スキルがありません (私たちは .NET C# ショップです)。

推奨されるアプローチに関する考えや提案は大歓迎です...

4

3 に答える 3

4

適切なHTMLパーサーを使用します。Perl用のHTML::Parserがあり、C#用にもいくつかあると確信しています。

于 2009-07-31T10:09:04.327 に答える
2

Perl、HTML::TokeParserおよびHTML::Templateを使用すると役立ちます。簡単な例を次に示します。

#!/usr/bin/perl

use strict;
use warnings;

use HTML::TokeParser;
use HTML::Template;

use Data::Dumper;

my ($html_file) = @ARGV;

open my $html_handle, '<:utf8', $html_file
    or die "Cannot open '$html_file': $!";

my $parser = HTML::TokeParser->new( $html_handle );

my @divs;

while ( my $tag = $parser->get_tag('div') ) {
    my $attr = $tag->[1];
    next unless ref $attr eq 'HASH';
    next unless defined( my $id = $attr->{id} );
    next unless $id eq 'div1' or $id eq 'div2';

    my $div = $tag->[-1];
    my $in_wanted = 1;

    while ( $in_wanted ) {
        my $token = $parser->get_token;
        if ( $token->[0] eq 'T' ) {
            $div .= $token->[1];
        }
        else {
            $div .= $token->[-1];
        }
        my ($type, $name) = @$token[0, 1];
        if ( $name eq 'div' ) {
            $in_wanted += $type eq 'S' ?  1
                        : $type eq 'E' ? -1
                        : 0;
            next;
        }
        if ( $type eq 'E' and $name eq 'html' ) {
            warn "Warning: Reached the end of '$html_file'\n";
            last;
        }
    }

    push @divs, {DIV => $div};
}

print output( @divs );

sub output {
    my $tmpl_html = <<EO_TMPL;
<html>
<body>
<TMPL_LOOP DIVS>
    <TMPL_VAR DIV>
</TMPL_LOOP>
</body>
</html>
EO_TMPL
    my $tmpl = HTML::Template->new(
        scalarref => \$tmpl_html,
    );
    $tmpl->param( DIVS => \@_ );
    return $tmpl->output;
}
于 2009-07-31T12:24:52.787 に答える
1

divにネストされたdivが含まれている場合は、単純な正規表現では不十分な場合があります。これは、終了div要素にIDが含まれていないため、正規表現が終了タグと一致するのが難しいためです。

divが次の場合:

<div id="findme">
    <!-- No other divs here! -->
</div>

次に、正規表現(貪欲に注意してください)を使用できます。これは、よりエレガントなバージョンです。

<div id="findme">(.*?)</div>

注:正規表現が実行されないことは間違いありません。しばらく経ちました。

HTMLパーサーライブラリを使用して構造を解析し、div内の文字オフセットを取得してから、その範囲をバッファーから取得することを検討します。HTMLライブラリを使用すると、目的のdivが終了する場所を解析して見つけることができます。

このチュートリアルのようなものが役立つかもしれません。これらのパーサーを使用すると、divなどのタグで囲まれたデータを正確に抽出できる可能性があります。

C#HTMLパーサーを使用することもできます。これらはすべて同様の機能を果たします。ドキュメントを調べて、ツリーを構築しただけではないことを確認し、囲まれたdivデータの文字オフセットを取得できるようにします(抽出できるようにします)。または、そのデータへのアクセスを許可します。

于 2009-07-31T10:11:23.197 に答える