Re: XSLT processing
"Jenda Krynicky" <[email protected]>
| Newsgroups | gmane.comp.lang.perl.xml |
|---|---|
| Message-ID | <[email protected]> |
From: Jakub Jezek <[email protected]> > After that I'll try to desribe, what I need to do with my xmls. > > I need to save tree structure of test, which are in <criterion> > elements. This tree structure has logical structure, which is given by > atribute @operator in elements <criteria>. > > And I am saving this data into DB. Examples are below: > XMLs: > http://forstman.kvalitne.cz/temp/jezza/com.redhat.rhsa-20091463.xml > http://forstman.kvalitne.cz/temp/jezza/com.redhat.rhsa-20091490.xml > > My dreamy output :) (DB's tables) : > http://forstman.kvalitne.cz/temp/jezza/nastrel_db_oval.pdf > > There are 2 tables, In criterias, I want to save just criteria groups > with their operator. In critrions, I need to save groups of tests, which > are in criteria. Each group of test is conected with a criteria. I hope > it's understandable. Something like this? #!perl use strict; use warnings; no warnings qw(uninitialized); use XML::Rules; { my $i=1; sub insertDefinition { print "INSERT INTO definitions (code) values ('$_[0]') --> ID=$i\n"; return $i++ } } { my $i=1; sub insertCriteria { print "INSERT INTO criterias (parent_id,type, cve_group_id) values ( $_[0], '$_[1]', $_[2]) --> ID=$i\n"; return $i++ } } { my $i=1; sub insertCriterion { print "INSERT INTO criterions (criteria_id, test_name) values ( $_[0], '$_[1]') --> ID=$i\n"; return $i++ } } my $parser = XML::Rules->new( rules => { '^definition' => sub { my ($tag,$attr) = @_; my $id = insertDefinition($attr->{id}); $attr->{':id'} = $id; return 1; }, '^criteria' => sub { my ($tag, $attr, $context, $parents) = @_; my $parent_id = ($context->[-1] eq 'criteria' ? $parents->[-1]{':id'} : 'null'); my $definition_id = ( $context->[2] eq 'definition' ? $parents->[2]{':id'} : die "<criteria> tag outside <definition> or <definition> in a different place in the hierarchy!'\n"); my $id = insertCriteria($parent_id, $attr->{operator}, $definition_id); $attr->{':id'} = $id; }, '^criterion' => sub { my ($tag, $attr, $context, $parents) = @_; my $parent_id = ( $context->[-1] eq 'criteria' ? $parents->[-1]{':id'} : die "<criterion> outside <criteria>!\n"); insertCriterion($parent_id, $attr->{test_ref}); return; }, _default => '', '^generator,metadata,tests,objects,states' => 'skip', } ); $parser->parse(\*DATA); __DATA__ <oval_definitions xmlns="... The database stuff is left to you, I do not know what database do you use and the autonumber field handling differs. I think the stubs are clear. The XML::Rules allows you to attach actions to start or end tags and build a tree structure of the data parsed for the not yet closed tags including the data produced by the handlers of the already closed child tags. In this case whenever the parser encounterd a <definition> tag it inserts the "id" into the database and remembers the assigned id. Later whenever it encounters a <criteria> tag it looks whether the parent tag was also <criteria>. If yes, it takes it's id, if not then the $parent_id will be null. Then if finds the definition id, inserts the data into the database and remembers the id. Lastly whenever it encounters a <criterion> tag it checks whether the parent was <criteria> and die()s if not. Otherwise it inserts the data including the parent tag's id into the database. The generator, metadata, tests, objects and states tags are skipped (this is just an optimization) and no data from closed tags is remembered. So once the file is parsed, it's in the database and very little data is kept in memory. Jenda ===== [email protected] === http://Jenda.Krynicky.cz ===== When it comes to wine, women and song, wizards are allowed to get drunk and croon as much as they like. -- Terry Pratchett in Sourcery _______________________________________________ Perl-XML mailing list [email protected] To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs