3

Author.pm、BillingPeriod.pm、Offer.pm、PaymentMethod.pm などのさまざまなモジュールがあり、要素の値に相当するモジュールのオブジェクトを作成したい終了要素タグをヒットするたびに、sax に表示されます。

どうすればこれを達成できますか?

たとえば、XML ファイルを解析して sax パーサーが end 要素をヒットした場合は、Offer.pm のオブジェクトを作成する必要があります。同様に、sax パーサーが end 要素タグをヒットした場合は、Author.pm のオブジェクトを作成する必要があります。

コード

XML:books.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2009 sp1 (http://www.altova.com)-->
<bks:books xsi:schemaLocation="urn:books Untitled1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bks="urn:books">
        <book id="String">
                <author>String</author>
                  <authorFirstName>String</authorFirstName>
                  <authorLastName>String</authorLastName>
                <title>String</title>
                   <titleNo>3</titleNo>
                <genre>String</genre>
                <offer>String</offer>
                <pub_date>1967-08-13</pub_date>
                <review>String</review>
                  <reviewsratings></reviewratings>
        </book>
</bks:books>

サックス:perlsaxparsing.pl

#!usr/bin/perl -w

use XML::SAX::ParserFactory;
use MySaxHandler;
my $handler = MySaxHandler->new();
my $parser = XML::SAX::ParserFactory->parser(Handler => $handler);
$parser->parse_uri("books.xml")

例えば以下の例では、サックスが打っていると仮定してOffer end element tagオブジェクトを作成しています。Offer.pm

モジュールのオブジェクトを作成したいのですが、たとえばOffer.pmこの場合、sax が Offer 要素タグの end 要素にヒットしたときなどです。

  package Offer;
    use strict;

    # This class depicts the product_offer details
    sub new {
        my $class = shift;
        my $self  = {
            _objectId        => shift,
            _price           => shift

        };
        bless $self, $class;
        return $self;
    }

    # Returns the ObjectID
    sub getObjectId {
        my ($self) = @_;
        return $self->{_objectId};
    }


    # Returns the Price
    sub getprice {
        my ($self) = @_;
        return $self->{_price};
    }

    # Check for undefined values and build a insert mapping table
    sub doPreInsetCheck() {
        my ($self) = @_;
        my %refTable;
        if ( defined $self->getObjectId == 1 ) {
            $refTable{'object_id'} = $self->getObjectId;
        }
        if ( defined $self->getprice == 1 ) {
            $refTable{'fk2_price'} = $self->getprice;
        }
        return %refTable;
    }

    # Returns the SQL Statement
    sub getSQLScript {
        my $tableName = 'product_offer';
        my ($self)    = @_;
        my $sqlOutput = "Insert into " . $tableName . "(";
        my %refTable  = $self->doPreInsetCheck();
        my @colNames  = keys %refTable;
        my $ctr;
        foreach ( $ctr = 0 ; $ctr < ( $#colNames + 1 ) ; $ctr++ ) {
            $sqlOutput .= $colNames[$ctr];
            if ( $ctr < $#colNames ) {
                $sqlOutput .= ",";
            }
        }
        $sqlOutput .= ") values (";
        my @colVals = values %refTable;
        foreach ( $ctr = 0 ; $ctr < ( $#colVals + 1 ) ; $ctr++ ) {
            $sqlOutput .= $colVals[$ctr];
            if ( $ctr < $#colVals ) {
                $sqlOutput .= ",";
            }
        }
        $sqlOutput .= ");";
        return $sqlOutput;
    }
    1;

SAX パーサー ハンドラー モジュール:MySaxHander.pm

sub end_element {
    my($self,$data) = @_;
    print "\t Ending element:".$data->{Name}."\n";
    my $obj = new Price("1","2","NL","ENUM","DESCRIPTION","2008-01-01  10:00:00","2009-01-01 10:00:00","2008-01-01 10:00:00","USER");
print $obj->getSQLScript."\n";
$in_books--;
}

質問: SAX を使用して XML ファイルを解析しているときに、要素 value に相当するモジュールのオブジェクトを作成するにはどうすればよいですか?

4

2 に答える 2

2

一般に、SAX で行う必要があることは次のとおりです。

  1. start_element の処理中に作業領域を作成し、ネストされたタグからの値を保持します。この値は、最終的にオブジェクトに入力する必要があります。
  2. end_element で、オブジェクトをインスタンス化します

または、(空の) オブジェクトを start_element でインスタンス化してから、ネストされた characters() および start_element() イベントを処理して入力することもできます。いずれの場合も、現在の処理状態を追跡する必要があるため、各要素タイプに遭遇したときに何をすべきかがわかります。また、階層内の論理的な位置を追跡し、現在のオブジェクト/ワークエリアを指すグローバル コンテキスト スタックも必要です。

これらの問題を扱う導入部へのポインタを次に示します。

于 2009-11-18T17:54:50.500 に答える
1

同じ XML を何度も見るのにうんざりしているので、あなたに魚を与えることにしました。あなた自身の利益のために、質問を説明するためにもっと努力する必要があります。つまり、投稿した XML にもエラーが含まれています。

以下のコードには、型にはまらない側面がいくつかあります。それらはそこにあるため、このコードを自分のコードとして上司/クライアントに渡す前に、何が起こっているのかを把握する必要があります。

#!/usr/bin/perl

package My::Book;
use strict; use warnings;

use base 'Class::Accessor::Faster';

 __PACKAGE__->follow_best_practice;

__PACKAGE__->mk_accessors(qw(
    id author authorFirstName authorLastName title titleNo
    genre offer pub_date review reviewsratings
));

package My::Handler;
use strict; use warnings;

{{

my ($current_element, $element_data);

sub new { bless $_[1] => $_[0] }

sub start_element {
    my ($self, $data) = shift;
    my ($el) = @_;

    if ( (my $local_name = $el->{LocalName}) eq 'book' ) {
        my $book = My::Book->new({
            id => $el->{Attributes}{'{}id'}{Value}
        });
        push @$self, $book;
    }
    elsif ( $local_name ne 'books' ) {
        $current_element = $el->{LocalName};
    }
    return;
}

sub characters {
    my ($self, $data) = @_;
    if ( defined $current_element ) {
        $element_data .= $data->{Data};
    }
    return;
}

sub end_element {
    my ($self, $el) = @_;

    unless ( (my $local_name = $el->{LocalName}) =~ /\Abooks?\z/ ) {
        my $accessor = "set_$local_name";
        $self->[-1]->$accessor($element_data);
    }
    $current_element = undef;
    $element_data = '';
    return;
}


}}

package main;
use strict; use warnings;

use XML::SAX;

my @books;

my $parser = XML::SAX::ParserFactory->parser(
    { Handler => My::Handler->new(\@books) },
);

$parser->parse_file(\*DATA);

for my $book ( @books ) {
    printf("%s by %s was published on %s\n",
        $book->get_title, $book->get_author, $book->get_pub_date
    );
}


__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2009 sp1 (http://www.altova.com)-->
<bks:books xsi:schemaLocation="urn:books Untitled1.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bks="urn:books">

<book id="String">
<author>String</author>
<authorFirstName>String</authorFirstName>
<authorLastName>String</authorLastName>
<title>String</title>
<titleNo>3</titleNo>
<genre>String</genre>
<offer>String</offer>
<pub_date>1967-08-13</pub_date>
<review>String</review>
<reviewsratings></reviewsratings>
</book>
</bks:books>

出力:

C:\Temp> ホイ
String by String は 1967-08-13 に公開されました
于 2009-11-19T00:29:56.310 に答える