#!/usr/bin/perl use strict 'vars'; use vars qw/ $VERSION /; $VERSION=0.55; #----*----*----*----*----*----*----*----*----*----*----*----*----*----*----* package XML::BMEcat; use IO::File; use XML::Generator; sub new { my $class = shift; my $self = {}; bless $self, $class; } sub setOutfile { my $self = shift; return unless $_[0]; my $XMLFILE = new IO::File "> $_[0]" or die "Can't open $_[0]: $!"; return $self->{'XMLFILE'} = $XMLFILE; } sub creatHeader { my $self = shift; return $self->{'INFO'} = Header->new(); } sub creatFeatureSystem { my $self = shift; return $self->{'FEATURE_GROUP_LIST'} = FeatureSystem->new(); } sub creatGroupSystem { my $self = shift; return $self->{'NODE_LIST'} = GroupSystem->new(); } sub getGroupSystem { my $self = shift; ($self->{'NODE_LIST'}) ? return $self->{'NODE_LIST'} : 0; } sub creatArticleSystem { my $self = shift; $self->{'ART_MAP'} = ArticleSystem->new(); $self->{'ART_MAP'}->bind2GroupSystem($self->getGroupSystem); return $self->{'ART_MAP'} } sub writeHeader { my $self = shift; ( $self->{'INFO'} ) ? my $INFO = $self->{'INFO'} : return -1; print "... Creating BME-Header ...\n" if $self->{'INFO'}->{'Config'}->{'VERBOSE'}; my ($sec, $min, $hour, $mday, $mon, $year) = localtime(time); my $agreement; my $transaction = $INFO->{'TRANSACTION'}; $transaction .= " prev_version=\"$INFO->{'PREV_VERSION'}\"" if $INFO->{'PREV_VERSION'}; $agreement = CreateTAGf (2, "AGREEMENT", "\n", CreateTAGf (3, "AGREEMENT_ID", $INFO->{'Agreement'}->{'AGREEMENT_ID'}), CreateTAGf (3, "DATETIME", {'type' => "agreement_start_date"}, "\n", CreateTAGf (4, "DATE", $INFO->{'Agreement'}->{'AGREEMENT_start_date'}), " " ), CreateTAGf (3, "DATETIME", {'type' => "agreement_end_date"}, "\n", CreateTAGf (4, "DATE", $INFO->{'Agreement'}->{'AGREEMENT_end_date'}), " " ), " " ) if $INFO->{'AGREEMENT'}; $self->{'XMLFILE'}->print( '{'Config'}->{'CHAR_SET'} . "\"?>\n\n", '{'Config'}->{'DTD'} . "\">\n\n", '' . "\n" . CreateTAGf (1, "HEADER", "\n", CreateTAGf (2, "GENERATOR_INFO", $INFO->{'General'}->{'GENERATOR_INFO'}), CreateTAGf (2, "CATALOG", "\n", CreateTAGf (3, "LANGUAGE", $INFO->{'General'}->{'LANGUAGE'}), CreateTAGf (3, "CATALOG_ID", $INFO->{'General'}->{'CATALOG_ID'}), CreateTAGf (3, "CATALOG_VERSION", $INFO->{'General'}->{'CATALOG_VERSION'}), CreateTAGf (3, "CATALOG_NAME", $INFO->{'General'}->{'CATALOG_NAME'} ), CreateTAGf (3, "DATETIME", {'type' => "generation_date"}, "\n", CreateTAGf (4, "DATE", $INFO->{'General'}->{'DATE'}), CreateTAGf (4, "TIME", $INFO->{'General'}->{'TIME'}), " ", ), CreateTAGf (3, "TERRITORY", $INFO->{'General'}->{'TERRITORY'}), CreateTAGf (3, "CURRENCY", $INFO->{'General'}->{'CURRENCY'}), CreateTAGf (3, "MIME_ROOT", $INFO->{'General'}->{'MIME_ROOT'}), " " ), CreateTAGf (2, "BUYER", "\n", CreateTAGf (3, "BUYER_ID", $INFO->{'Buyer'}->{'BUYER_ID'}), CreateTAGf (3, "BUYER_NAME", $INFO->{'Buyer'}->{'BUYER_NAME'}), CreateTAGf (3, "ADDRESS", {'type' => "buyer"}, "\n", CreateTAGf (4, "NAME", $INFO->{'Buyer'}->{'NAME'}), CreateTAGf (4, "NAME2", $INFO->{'Buyer'}->{'NAME2'}), CreateTAGf (4, "CONTACT", $INFO->{'Buyer'}->{'CONTACT'}), CreateTAGf (4, "STREET", $INFO->{'Buyer'}->{'STREET'}), CreateTAGf (4, "ZIP", $INFO->{'Buyer'}->{'ZIP'}), CreateTAGf (4, "CITY", $INFO->{'Buyer'}->{'CITY'}), CreateTAGf (4, "COUNTRY", $INFO->{'Buyer'}->{'COUNTRY'}), CreateTAGf (4, "PHONE", $INFO->{'Buyer'}->{'PHONE'}), CreateTAGf (4, "FAX", $INFO->{'Buyer'}->{'FAX'}), CreateTAGf (4, "EMAIL", $INFO->{'Buyer'}->{'EMAIL'}), CreateTAGf (4, "URL", $INFO->{'Buyer'}->{'URL'}), " " ), " " ) . $agreement . CreateTAGf (2, "SUPPLIER", "\n", CreateTAGf (3, "SUPPLIER_ID", {'type' => $INFO->{'Supplier'}->{'SUPPLIER_ID'}->[0]}, $INFO->{'Supplier'}->{'SUPPLIER_ID'}->[1]), CreateTAGf (3, "SUPPLIER_NAME", $INFO->{'Supplier'}->{'SUPPLIER_NAME'}), CreateTAGf (3, "ADDRESS", {'type' => "supplier"}, "\n", CreateTAGf (4, "NAME", $INFO->{'Supplier'}->{'NAME'}), CreateTAGf (4, "NAME2", $INFO->{'Supplier'}->{'NAME2'}), CreateTAGf (4, "CONTACT", $INFO->{'Supplier'}->{'CONTACT'}), CreateTAGf (4, "STREET", $INFO->{'Supplier'}->{'STREET'}), CreateTAGf (4, "ZIP", $INFO->{'Supplier'}->{'ZIP'}), CreateTAGf (4, "CITY", $INFO->{'Supplier'}->{'CITY'}), CreateTAGf (4, "COUNTRY", $INFO->{'Supplier'}->{'COUNTRY'}), CreateTAGf (4, "PHONE", $INFO->{'Supplier'}->{'PHONE'}), CreateTAGf (4, "FAX", $INFO->{'Supplier'}->{'FAX'}), CreateTAGf (4, "EMAIL", $INFO->{'Supplier'}->{'EMAIL'}), CreateTAGf (4, "URL", $INFO->{'Supplier'}->{'URL'}), " " ), " " ), " " ) . " <$transaction>" . "\n" ); return 0; } sub writeFeatureSystem { my $self = shift; ( $self->{'FEATURE_GROUP_LIST'} ) ? my $FEATURE_GROUP_LIST = $self->{'FEATURE_GROUP_LIST'} : return -1 ; my $FeatureGroupID = ""; my $type; print "... Creating BME-Feature-System ...\n" if $self->{'INFO'}->{'Config'}->{'VERBOSE'}; $self->{'XMLFILE'}->print( " \n", " $self->{'INFO'}->{'Config'}->{'FEATURE_SYSTEM_NAME'}\n" ); foreach $FeatureGroupID ( sort keys( %$FEATURE_GROUP_LIST ) ) { $self->{'XMLFILE'}->print( " \n", " $FeatureGroupID\n", " ", sprintf ("GENERIC_%d", $FeatureGroupID), "\n" ); my $sort = 10; foreach (@{$FEATURE_GROUP_LIST->{"$FeatureGroupID"}}) { my ($feature, $unit) = @{$_}; if ($unit) { $type = "free_entry" } else { $type = "defaults" }; $self->{'XMLFILE'}->print( " \n", " $feature\n" ); $self->{'XMLFILE'}->print( " $unit\n"); $self->{'XMLFILE'}->print( " $sort\n", " \n" ); $sort +=10; } $self->{'XMLFILE'}->print(" \n"); } $self->{'XMLFILE'}->print(" \n"); return 0 } sub writeGroupSystem { my $self = shift; ( $self->{'NODE_LIST'} ) ? my $NODE_LIST = $self->{'NODE_LIST'} : return -1; ( $self->{'INFO'} ) ? my $INFO = $self->{'INFO'} : return -1; my ($type, %ReverseIdx); print "... Creating BME-Catalog-Structure ...\n" if $self->{'INFO'}->{'Config'}->{'VERBOSE'}; $self->{'XMLFILE'}->print( " \n", CreateTAGf (3, "GROUP_SYSTEM_ID", $INFO->{'Config'}->{'GROUP_SYSTEM_ID'}) ); foreach (keys %$NODE_LIST) { $ReverseIdx{$NODE_LIST->{$_}} = $_ } foreach (@$NODE_LIST) { next unless $ReverseIdx{$_}; # because the Pseudohash ! my $group_id = $ReverseIdx{$_}; my $desc; if ( ! $NODE_LIST->{$group_id}->{'PARENT'} ) { # no parents :-(, root ? $type = "root"; } elsif ( $NODE_LIST->{$group_id}->{'LEAF'} ) { # leaf ? $type = "leaf"; } else { # "normal" node ? $type = "node"; } if ($NODE_LIST->{$group_id}->{'DESCR'}) { # node-description ? my $txt; foreach ( @{$NODE_LIST->{$group_id}->{'DESCR'}} ) { my ($TextArt, $Text) = @{$_}[1,2]; if ( ! ($TextArt =~ /Tabellenunterschrift.*/i) ) { $txt .= ' ' if ($txt); $txt .= "$Text" ; } } $desc = CreateTAGf (4, "GROUP_DESCRIPTION", $txt ) if ( $txt ); } $self->{'XMLFILE'}->print ( CreateTAGf (3, "CATALOG_STRUCTURE", {'type' => $type}, "\n", CreateTAGf (4, "GROUP_ID", $group_id), CreateTAGf (4, "GROUP_NAME", $NODE_LIST->{$group_id}->{'NAME'}), $desc, CreateTAGf (4, "PARENT_ID", $NODE_LIST->{$group_id}->{'PARENT'}), CreateTAGf (4, "GROUP_ORDER", $NODE_LIST->{$group_id}->{'SORT'}), MIME_INFO($NODE_LIST->{$group_id}->{'MIME'}, 4), " " ) ) } $self->{'XMLFILE'}->print(" \n"); return 0 } sub writeArticleSystem { my $self = shift; ( $self->{'ART_MAP'} ) ? my $ART_MAP = $self->{'ART_MAP'} : return -1; my $ret; print "... Creating BME-Articles-Details ...\n" if $self->{'INFO'}->{'Config'}->{'VERBOSE'}; foreach my $IDX (sort keys ( %$ART_MAP )) { next if $IDX =~ /^#~_/ or ! $IDX; my $str = ""; $str .= $ret if $ret = ArticleDetails($ART_MAP->{$IDX}, 'ARTICLE_DETAILS'); if ( $self->{'FEATURE_GROUP_LIST'} and $ART_MAP->{$IDX}->{FT_GROUP} ) { $str .= $ret if $ret = ArticleFeatures( $ART_MAP->{$IDX}, $self->{'FEATURE_GROUP_LIST'}, $self->{'INFO'}->{'Config'}->{'FEATURE_SYSTEM_NAME'} ) }; $str .= $ret if $ret = ArticleDetails($ART_MAP->{$IDX}, 'ARTICLE_ORDER_DETAILS'); $str .= $ret if $ret = ArticleDetails($ART_MAP->{$IDX}, 'ARTICLE_PRICE_DETAILS'); $str .= $ret if $ret = MIME_INFO($ART_MAP->{$IDX}->{'MIME'}, 3); $self->{'XMLFILE'}->print ( CreateTAGf (2, "ARTICLE", {'mode' => $ART_MAP->{$IDX}->{'mode'}}, "\n", CreateTAGf (3, "SUPPLIER_AID", $ART_MAP->{$IDX}->{'SUPPLIER_AID'}), $str, " " ) ) } return 0 } sub ArticleDetails { return unless ( $_[0] && ref $_[0] ); # no reference to ART_DETAILS ? my $ref = shift; my $key1 = shift; my ($str); if ($key1 eq 'ARTICLE_PRICE_DETAILS') { foreach my $key2 ( qw/DATETIME ARTICLE_PRICE /) { foreach my $r_list ( @{$ref->{$key1}->{$key2}} ) { my $str1 = ""; my ($type, $value) = splice @{$r_list}, 0, 2; while (my ($tag, $val) = splice @{$r_list}, 0, 2) { $str1 .= CreateTAGf (5, $tag, $val); } $str .= CreateTAGf (4, $key2, {$type => $value}, "\n", $str1, " ") if $str1; } } } else { foreach (@{$ref->{$key1}}) { if ( ref $_ && $_->[1] ) { if ( ref $_->[1] ) { $str .= CreateTAGf (4, $_->[0], {'type' => $_->[1]->[0]}, $_->[1]->[1]); } else { $str .= CreateTAGf (4, $_->[0], $_->[1]); } } } } return CreateTAGf (3, "$key1", "\n", $str, " ") if $str; } sub ArticleFeatures { my $ref = shift; my $FEATURE_GROUP_LIST = shift; my $str1 = CreateTAGf (4, 'REFERENCE_FEATURE_SYSTEM_NAME', shift); # unless ($ref->{'FT_GROUP'}) { printf "Skipping ArticleFeatures for: %s\n", $ref->{'SUPPLIER_AID'}; return ""}; $str1 .= CreateTAGf (4, 'REFERENCE_FEATURE_GROUP_ID', $ref->{'FT_GROUP'}); foreach ( @{$FEATURE_GROUP_LIST->{$ref->{'FT_GROUP'}}} ) { my $str = ""; my ($feature, $unit) = @{$_}; my $value = shift @{$ref->{'ARTICLE_FEATURES'}}; $str .= CreateTAGf (5, 'FNAME', $feature) . CreateTAGf (5, 'FVALUE', $value); $str .= CreateTAGf (5, 'FUNIT', $unit) if $unit; $str1 .= CreateTAGf (4, 'FEATURE', "\n", $str, " ") if $str; } return CreateTAGf (3, 'ARTICLE_FEATURES', "\n", $str1, " ") if $str1; } sub writeArticleGroupMap { my $self = shift; ( $self->{'ART_MAP'} ) ? my $ART_MAP = $self->{'ART_MAP'} : return -1; my $art_id; print "... Creating BME-Catalog-Article-Mapping ...\n" if $self->{'INFO'}->{'Config'}->{'VERBOSE'}; foreach my $IDX (keys %$ART_MAP) { next if $IDX =~ /^#~_/ or ! $IDX; if ( @{$ART_MAP->{$IDX}->{'ARTICLE_DETAILS'}}[2] ) { # EAN exists ? $art_id = $ART_MAP->{$IDX}->{'ARTICLE_DETAILS'}->[2]->[1]; } else { $art_id = $ART_MAP->{$IDX}->{'SUPPLIER_AID'} } foreach my $LEAF (@{$ART_MAP->{$IDX}->{'PARENTS'}}) { $self->{'XMLFILE'}->print( CreateTAGf (2, "ARTICLE_TO_CATALOGGROUP_MAP", "\n", CreateTAGf (3, "ART_ID", $art_id), CreateTAGf (3, "CATALOG_GROUP_ID", $LEAF), " " ) ) } } return 0 } sub writeTail { my $self = shift; ( $self->{'INFO'} ) ? my $INFO = $self->{'INFO'} : return -1; print "... Creating BME-Tail ...\n" if $self->{'INFO'}->{'Config'}->{'VERBOSE'}; $self->{'XMLFILE'}->print(" {'TRANSACTION'}>\n\n"); return 0 } sub MIME_INFO { return unless ( $_[0] && ref $_[0] ); # no reference to MIME_INFOS ? my $REF = shift; my $indent = shift; my $mime = ""; my $morder = 1; foreach ( @{$REF} ) { my ($mtype, $msource, $description, $purpose) = @{$_}; $mime .= CreateTAGf ($indent + 1, "MIME", "\n", CreateTAGf ($indent + 2, "MIME_TYPE", $mtype), CreateTAGf ($indent + 2, "MIME_SOURCE", $msource), CreateTAGf ($indent + 2, "MIME_DESCR", $description), CreateTAGf ($indent + 2, "MIME_PURPOSE", $purpose), CreateTAGf ($indent + 2, "MIME_ORDER", $morder++), substr " ", 0, 3*($indent+1) ) } return CreateTAGf ($indent, "MIME_INFO", "\n", $mime, substr " ", 0, 3*$indent); } my $xmlgen; sub CreateTAGf { my ($indent, $TAG, @rest) = @_; my $xmlgen = new XML::Generator or die $! unless defined $xmlgen; map { s/&([^amp])/&$1/g; # s//>/g; s/\x96{1}/x/g } @rest; # clean fields my $Spaces = substr " ", 0, 3*$indent; return ($Spaces . $xmlgen->$TAG(@rest) . "\n"); } #----*----*----*----*----*----*----*----*----*----*----*----*----*----*----* package Header; sub new { my $class = shift; my $self = {}; bless $self, $class; } sub setTransaction { my $self = shift; $self->{'TRANSACTION'} = shift; $self->{'PREV_VERSION'} = $_[0]->[1] if ref $_[0] and $_[0]->[0] =~ /^prev_version/i; } sub setGeneralInfo { my $self = shift; while (my ($tag, $val) = splice @_, 0, 2) { $self->{'General'}->{$tag} = $val; } } sub setBuyerInfo { my $self = shift; while (my ($tag, $val) = splice @_, 0, 2) { $self->{'Buyer'}->{$tag} = $val; } } sub setAgreementInfo { my $self = shift; while (my ($tag, $val) = splice @_, 0, 2) { $self->{'Agreement'}->{$tag} = $val; } } sub setSupplierInfo { my $self = shift; while (my ($tag, $val) = splice @_, 0, 2) { $self->{'Supplier'}->{$tag} = $val; } } sub setConfigInfo { my $self = shift; while (my ($tag, $val) = splice @_, 0, 2) { $self->{'Config'}->{$tag} = $val; } } #----*----*----*----*----*----*----*----*----*----*----*----*----*----*----* package FeatureSystem; sub new { my $class = shift; my $self = {}; bless $self, $class; } sub addFeatureGroup { my $self = shift; my $key = shift; return "" if exists $self->{$key}; $self->{$key} = []; while (my ($tag, $val) = splice @_, 0, 2) { push @{$self->{$key}}, [ "$tag" => "$val" ]; } return $self->{$key}; } #----*----*----*----*----*----*----*----*----*----*----*----*----*----*----* package GroupSystem; sub new { my $class = shift; my $self = [{}]; bless $self, $class; } sub creatCatalogGroup { my ($self, $key) = @_; # pls.don't forget this problem (exists $self->{$key}) ? return $self->{$key} : return Push2PsH($self, $key, CatalogGroup->new()); } sub Push2PsH { my ($struct, $key, $val) = @_; $struct->[0]->{$key} = @$struct; push @$struct, $val; return $val; } sub getCatalogGroup { my ($self, $key) = @_; if (exists $self->{$key}) { return $self->{$key} } else { return 0 } } #----*----*----*----*----*----*----*----*----*----*----*----*----*----*----* package CatalogGroup; sub new { my $class = shift; my $self = {}; $self->{'MEMBERS'} = []; bless $self, $class; } sub setData { my $self = shift; while (my ($tag, $val) = splice @_, 0, 2) { $self->{$tag} = "$val"; } } sub getData { my $self = shift; my $Key = shift; return $self->{$Key} if exists $self->{$Key}; } sub addDescription { my $self = shift; push @{$self->{'DESCR'}}, [ "", "" => shift ]; } sub addMime { my $self = shift; my @list = @_; push @{$self->{'MIME'}}, \@list; } sub addMember { my $self = shift; push @{$self->{'MEMBERS'}}, shift; } sub getMembers { my $self = shift; return $self->{'MEMBERS'}; } #----*----*----*----*----*----*----*----*----*----*----*----*----*----*----* package ArticleSystem; sub new { my $class = shift; my $self = {}; bless $self, $class; } sub bind2GroupSystem { my $self = shift; $self->{'#~_GROUP_SYSTEM'} = shift; } sub getGroupSystem { my $self = shift; return $self->{'#~_GROUP_SYSTEM'} if exists $self->{'#~_GROUP_SYSTEM'}; } sub creatArticle { my $self = shift; my $key = shift; return $self->{$key} = Article->new($key, $self->getGroupSystem); } sub getArticel { my ($self, $key) = @_; return $self->{$key}; } #----*----*----*----*----*----*----*----*----*----*----*----*----*----*----* package Article; sub new { my ($class, $Key, $GroupSystem) = @_; my $self = {}; $self->{'ART_KEY'} = $Key; $self->{'#~_GROUP_SYSTEM'} = $GroupSystem if $GroupSystem; bless $self, $class; } sub getKey { my $self = shift; return $self->{'ART_KEY'} if exists $self->{'ART_KEY'}; } sub setMainInfo { my $self = shift; while (my ($tag, $val) = splice @_, 0, 2) { $self->{$tag} = $val; } } sub setFeatureGroup { my $self = shift; $self->{'FT_GROUP'} = shift if $_[0]; } sub setFeatureValues { my $self = shift; my @list = @_; $self->{'ARTICLE_FEATURES'} = \@list; } sub addMime { my $self = shift; my @list = @_; push @{$self->{'MIME'}}, \@list; } sub setDetails { my $self = shift; my $idx = { 'DESCRIPTION_SHORT' => 0, 'DESCRIPTION_LONG' => 1, 'EAN' => 2, 'SUPPLIER_ALT_AID' => 3, 'BUYER_AID' => 4, 'MANUFACTURER_AID' => 5, 'MANUFACTURER_NAME' => 6, 'ERP_GROUP_BUYER' => 7, 'ERP_GROUP_SUPPLIER' => 8, 'DELIVERY_TIME' => 9, 'SPECIAL_TREATMENT_CLASS' => 10, 'KEYWORD' => 11, 'REMARKS' => 12, 'ARTICLE_ORDER' => 13, 'SEGMENT' => 14, 'ARTICLE_STATUS' => 15 }; while (my ($tag, $val) = splice @_, 0, 2) { unless ( defined $idx->{$tag} ) { warn "### ArticleDetails: wrong tag \"$tag\" !"; next; }; @{$self->{'ARTICLE_DETAILS'}}[$idx->{$tag}] = [ $tag => $val ]; } } sub setOrderDetails { my $self = shift; my $idx = { 'ORDER_UNIT' => 0, 'CONTENT_UNIT' => 1, 'NO_CU_PER_OU' => 2, 'PRICE_QUANTITY' => 3, 'QUANTITY_MIN' => 4, 'QUANTITY_INTERVAL' => 5 }; while (my ($tag, $val) = splice @_, 0, 2) { unless ( defined $idx->{$tag} ) { warn "### ArticleOrderDetails: wrong tag \"$tag\" !"; next; }; @{$self->{'ARTICLE_ORDER_DETAILS'}}[$idx->{$tag}] = [ $tag => $val ]; } } sub setPriceDetails { my $self = shift; while (my ($typ, $val) = splice @_, 0, 2) { push @{$self->{'ARTICLE_PRICE_DETAILS'}->{'DATETIME'}}, [ 'type' => $typ, 'DATE' => $val ]; } } sub addPrice { my $self = shift; my @list = (); my $order; while (my ($tag, $val) = splice @_, 0, 2) { if ( $tag =~ /^order$/i ) { $order = $val; next; } push @list, $tag, $val; } if ( $order ) { $self->{'ARTICLE_PRICE_DETAILS'}->{'ARTICLE_PRICE'}[$order] = \@list; } else { push @{$self->{'ARTICLE_PRICE_DETAILS'}->{'ARTICLE_PRICE'}}, \@list } } sub map2Group { my ($self, $GroupKey) = @_; push @{$self->{PARENTS}}, $GroupKey; my $CatalogGroup = ""; $CatalogGroup = $self->{'#~_GROUP_SYSTEM'}->getCatalogGroup($GroupKey) if exists $self->{'#~_GROUP_SYSTEM'}; if ($CatalogGroup) { $CatalogGroup->addMember($self->getKey); } else { print "No Groupssystem or Cataloggroup: $GroupKey\n"; } } #----*----*----*----*----*----*----*----*----*----*----*----*----*----*----* 1; __END__ =head1 NAME XML::BMEcat - Perl extension for generating BMEcat-XML =head1 SYNOPSIS use XML::BMEcat; my $BMEcat = XML::BMEcat->new(); $BMEcat->setOutfile("catalog.xml"); =head1 DESCRIPTION XML::BMEcat is a simple module to help in the generation of BMEcat-XML. Basically, you create an XML::BMEcat object and then call the related methods with the necessary parameters. =head1 METHODS The following methods are provided: =head2 HEADER Writes the BMEcat-Header: =over 4 =item * createHeader my $Header = $BMEcat->creatHeader(); =item * setTransaction $Header->setTransaction($TRANSACTION, [ 'PREV_VERSION' => $prev_version ]); =item * setGeneralInfo $Header->setGeneralInfo( 'GENERATOR_INFO' => $GENERATOR_INFO, 'LANGUAGE' => $LANGUAGE, 'CATALOG_ID' => $CATALOG_ID, 'CATALOG_VERSION' => $CATALOG_VERSION, 'CATALOG_NAME' => $CATALOG_NAME, 'DATE' => $DATE, 'TIME' => $TIME, 'CURRENCY' => $CURRENCY, 'MIME_ROOT' => $MIME_ROOT ); =item * setBuyerInfo $Header->setBuyerInfo( 'BUYER_ID' => $BUYER_ID, 'BUYER_NAME' => $BUYER_NAME, 'NAME' => $NAME, 'STREET' => $STREET, 'ZIP' => $ZIP, 'CITY' => $CITY, 'COUNTRY' => $COUNTRY, 'EMAIL' => $EMAIL, 'URL' => $URL ); =item * setAgreementInfo $Header->setAgreementInfo( 'AGREEMENT_ID' => $AGREEMENT_ID, 'AGREEMENT_start_date' => $AGREEMENT_start_date, 'AGREEMENT_end_date' => $AGREEMENT_end_date ); =item * setSupplierInfo $Header->setSupplierInfo( 'SUPPLIER_ID' => $SUPPLIER_ID, 'SUPPLIER_NAME' => $SUPPLIER_NAME, 'NAME' => $NAME, 'NAME2' => $NAME2, 'CONTACT' => $CONTACT, 'STREET' => $STREET, 'ZIP' => $ZIP, 'CITY' => $CITY, 'COUNTRY' => $COUNTRY, 'PHONE' => $PHONE, 'FAX' => $FAX, 'EMAIL' => $EMAIL, 'URL' => $URL ); =item * setConfigInfo $Header->setConfigInfo( 'VERSION' => $BMEcat_VERSION, 'CHAR_SET' => $CHAR_SET, 'DTD' => $DTD, 'VERBOSE' => 1 ); =item * writeHeader $BMEcat->writeHeader(); =back =head2 FEATURE_SYSTEM Writes the BMEcat - Feature-System: =over 4 =item * setConfigInfo $Header->setConfigInfo('FEATURE_SYSTEM_NAME' => $FEATURE_SYSTEM_NAME); =item * creatFeatureSystem my $FeatureSystem = $BMEcat->creatFeatureSystem(); =item * addFeatureGroup $FeatureSystem->addFeatureGroup( 'ftg1', 'ft1' => $unit_a, 'ft2' => $unit_b, 'ft3' => $unit_c, ); $FeatureSystem->addFeatureGroup( 'ftg2', 'ft4' => $unit_d, 'ft5' => $unit_e, 'ft6' => $unit_f, ); =item * writeFeatureSystem $BMEcat->writeFeatureSystem(); =back =head2 GROUP_SYSTEM Writes the BMEcat - Catalog-Structure: =over 4 =item * setConfigInfo $Header->setConfigInfo('GROUP_SYSTEM_ID' => $GROUP_SYSTEM_ID); =item * creatGroupSystem my $GroupSystem = $BMEcat->creatGroupSystem(); =item * creatCatalogGroup my $CatalogGroup = $GroupSystem->creatCatalogGroup($group_id); =item * getCatalogGroup my $CatalogGroup = $GroupSystem->getCatalogGroup($group_id); =item * setData $CatalogGroup->setData( 'PARENT' => 0, 'NAME' => $name02, 'SORT' => 5 ); $CatalogGroup = $GroupSystem->creatCatalogGroup('04'); $CatalogGroup->setData( 'PARENT' => 2, 'NAME' => $name04, 'SORT' => 5 ); $CatalogGroup = $GroupSystem->creatCatalogGroup('06'); $CatalogGroup->setData( 'PARENT' => 2, 'NAME' => $name06, 'SORT' => 10 ); $CatalogGroup = $GroupSystem->creatCatalogGroup('08'); $CatalogGroup->setData( 'PARENT' => 4, 'NAME' => $name08, 'SORT' => 5, 'LEAF' => 1 ); =item * getData $CatalogGroup->getData('PARENT'); =item * addDescription $CatalogGroup->addDescription($Description08); =item * addMime $CatalogGroup->addMime($type, $source, $description, $purpose); $CatalogGroup = $GroupSystem->creatCatalogGroup('10'); $CatalogGroup->setData( 'PARENT' => 4, 'NAME' => $name10, 'SORT' => 10, 'LEAF' => 1 ); =item * addMember $CatalogGroup->addMember('foo'); =item * getMembers my @members = $CatalogGroup->getMembers; =item * writeGroupSystem $BMEcat->writeGroupSystem() and print "not "; =back =head2 ARTICLES Writes the BMEcat - Article-Entrys: =head3 General =over 4 =item * creatArticleSystem my $ArticleSystem = $BMEcat->creatArticleSystem(); =item * writeArticleSystem $BMEcat->writeArticleSystem(); =item * getGroupSystem my $GroupSystem = ArticleSystem->getGroupSystem(); =item * creatArticle my $Article = $ArticleSystem->creatArticle($index); =item * getArticel my $Article = $ArticleSystem->getArticle($index); =item * getKey my $ArticleKey = $Article->getKey; =item * setMainInfo $Article->setMainInfo('mode' => $mode, 'SUPPLIER_AID' => $SUPPLIER_AID ); =back =head3 Features =over 4 =item * setFeatureGroup $Article->setFeatureGroup($group_id); =item * setFeatureValues $Article->setFeatureValues( $ft_val1, $ft_val2, $ft_val3, $ft_val4 ); =back =head3 Details =over 4 =item * addMime Several mimes are possible. See the BMEcat-spezification for more details. $Article->addMime( $mime_type, $mime_source, $description, $mime_purpose ); =item * setDetails All in the BMEcat-spezification described elements are allowed to set in free order and at several times. $Article->setDetails( 'DESCRIPTION_SHORT' => $DESCRIPTION_SHORT, 'DESCRIPTION_LONG' => $DESCRIPTION_LONG, 'EAN' => $EAN, . . . , 'SPECIAL_TREATMENT_CLASS' => [ $type => $val ], . . . ); =back =head3 Orderdetails =over 4 All in the BMEcat-spezification described elements are allowed to set in free order and at several times. $Article->setOrderDetails( 'ORDER_UNIT' => $ORDER_UNIT, 'CONTENT_UNIT' => $CONTENT_UNIT, 'NO_CU_PER_OU' => $NO_CU_PER_OU . . . ); =back =head3 Pricedetails =over 4 Several prices and types are possible. See the BMEcat-Spezification for more details. =item * setPriceDetails $Article->setPriceDetails( 'valid_start_date' => $start_date, 'valid_end_date' => $end_date ); =item * addPrice $Article->addPrice( 'price_type' => $price_type, 'PRICE_AMOUNT' => $price_amount, 'PRICE_CURRENCY' => $currency, 'TAX' => $tax ); =back =head2 ART_GROUP_MAP =over 4 Maps Articles to the BMEcat - Catalog-Structure: =item * map2Group $Article->map2Group($group_id); =item * writeArticleGroupMap $BMEcat->writeArticleGroupMap(); =back =head2 TAIL =over 4 =item * writeTail Writes the Tail and closes the BMEcat - Document $BMEcat->writeTail(); =back =head1 BUGS At this time not usable: - FEATURE_GROUP_NAME - DAILY_PRICE =head1 LIMITATIONS Not all BMEcat-features (eg. CLASSIFICATION_SYSTEM) have been implemented yet. See method-descriptions for detailed informations. =head1 SEE ALSO =over 4 =item The BMEcat-Authors http://www.BMEcat.org =item Perl-XML FAQ http://www.perlxml.com/faq/perl-xml-faq.html =back =head1 ACKNOWLEDGMENTS I'd like to thank Larry Wall, Randolph Schwarz, Tom Christiansen, Gurusamy Sarathy and many others for making Perl what it is today. I had the privilege of working with a really excellent teacher, Robert Krüger. He have guided me through the entire process and his criticisms where always right on. =head1 COPYRIGHT Copyright 2000-2003 by Frank-Peter Reich (fp$), fpreich@cpan.org This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. BMEcat is a trademark of BME - Bundesverband Materialwirtschaft, Einkauf und Logistik e.V.