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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.