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 )