NLP-GATE

 view release on metacpan or  search on metacpan

lib/NLP/GATE/Document.pm  view on Meta::CPAN


sub fromXML {
  my $self = shift;
  my $xml = shift;
  my $parser = XML::LibXML->new();
  _setParserOptions($parser);
  my $doc = $parser->parse_string($xml);
  _parseXML($self,$doc);
  return $self;
}


sub _setParserOptions {
  my $parser = shift;
  $parser->validation(0);
  $parser->recover(0);
  $parser->expand_entities(1);
  $parser->keep_blanks(1);
  $parser->pedantic_parser(1);
  $parser->line_numbers(1);
  $parser->load_ext_dtd(0);
  $parser->complete_attributes(0);
  $parser->expand_xinclude(0);
  $parser->no_network(1);
}

sub _parseXML {
  my $self = shift;
  my $doc = shift;
  my $root = $doc->getDocumentElement();
  ## process the document features
  my $i = 0;
  for my $feature ($doc->findnodes("/GateDocument/GateDocumentFeatures/Feature")) {
    my @n = $feature->findnodes("Name");
    my @v = $feature->findnodes("Value");
    #my @t = $feature->findnodes('Value/@className');
    if(@n && @v) {
      unless(scalar @n == 1) {
        croak "Strange document format: not exactly one Name element for document feature!";
      }
      unless(scalar @v == 1) {
        croak "Strange document format: not exactly one Value element for document feature!";
      }
      my $fname = $n[0]->textContent();
      $self->{features}->{$fname} = $v[0]->textContent();
      $self->{featuretypes}->{$fname} = $v[0]->getAttribute("className");
    }
  }
  ## process the document text and create a map of node ids to text offsets
  my %nodemap = ();
  my $offset = 0;
  my $text = "";
  for my $el ($doc->findnodes("/GateDocument/TextWithNodes")) {
    foreach my $c ($el->childNodes()) {
      if($c->nodeType() == 1) {  # element node
        ## get the attribute id
        my $nodeid = _getAttr($c,"id");
        $nodemap{$nodeid} = $offset;
      } elsif($c->nodeType() == 3 || $c->nodeType() == 4) {
        ## 3: text
        ## 4: cdata
        my $t = $c->textContent();
        $offset += length($t);
        $text .= $t;
      } else {
        croak "Invalid node type encountered: ",$c->nodeType(),"\n";
      }
    }
  }
  $self->{text} = $text;
  ## process the annotation features, replacing node ids with offset information
  for my $annset ($doc->findnodes("/GateDocument/AnnotationSet")) {
    ## figure out the name, then create a new annotation set
    my $name = _getAttr($annset,"Name","");
    my $myannset = NLP::GATE::AnnotationSet->new();

    ## find all the annotations in that annotation set
    for my $ann ($annset->findnodes("Annotation")) {
      # get attributes Id, Type, StartNode, EndNode
      my $annId = _getAttr($ann,"Id");
      my $annType = _getAttr($ann,"Type");
      my $annStartNode = _getAttr($ann,"StartNode");
      my $annEndNode = _getAttr($ann,"EndNode");
      my $from = $nodemap{$annStartNode};
      my $to   = $nodemap{$annEndNode};
      my $myann = NLP::GATE::Annotation->new($annType,$from,$to);
      for my $feature ($ann->findnodes("Feature")) {
        my @n = $feature->findnodes("Name");
        my @v = $feature->findnodes("Value");
        my @t = $feature->findnodes('Value/@className');
        if(@n && @v) {
          unless(scalar @n == 1) {
            croak "Strange document format: not exactly one Name element for document feature!";
          }
          unless(scalar @v == 1) {
            croak "Strange document format: not exactly one Value element for document feature!";
          }
          my $fname = $n[0]->textContent();
          $myann->setFeature($fname,$v[0]->textContent());
          $myann->setFeatureType($fname,$v[0]->getAttribute("className"));
        }
      } # for feature
      $myannset->add($myann);
    } # for ann
    $self->{annotationsets}->{$name} = $myannset;
  } # for annset

}

sub _getAttr {
  ## TODO: use node->getAttribute(name) instead!
  my $el = shift;
  my $attrname = shift;
  my $default = shift;
  my $val = $el->getAttribute($attrname);
  if(defined($val)) {
    return $val;
  } elsif(defined($default)) {
    return $default;
  } else {
    croak "Attribute $attrname not found in element ",$el->toString()," and no default";



( run in 1.922 second using v1.01-cache-2.11-cpan-7fcb06a456a )