# $Id: OWLParser.pm 1890 2008-02-14 10:59:57Z erant $ # # Module : OWLParser.pm # Purpose : Parse OWL files (oboInOwl mapping). # License : Copyright (c) 2006, 2007, 2008 Erick Antezana. All rights reserved. # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # Contact : Erick Antezana # package OBO::Parser::OWLParser; =head1 NAME OBO::Parser::OWLParser - An OWL parser (oboInOwl mapping). =head1 SYNOPSIS use OBO::Parser::OWLParser; use strict; my $my_parser = OBO::Parser::OWLParser->new; my $ontology = $my_parser->work("cco.owl"); =head1 DESCRIPTION An OWLParser object works on parsing an OWL file which is compliant with the OBO to OWL mapping described here: http://www.bioontology.org/wiki/index.php/OboInOwl:Main_Page =head1 AUTHOR Erick Antezana, Eerant@psb.ugent.beE =head1 COPYRIGHT AND LICENSE Copyright (C) 2006, 2007, 2008 by Erick Antezana This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.7 or, at your option, any later version of Perl 5 you may have available. =cut use OBO::Core::Term; use OBO::Core::Ontology; use OBO::Core::Dbxref; use OBO::Core::Relationship; use OBO::Core::RelationshipType; use XML::Parser; use Data::Dumper; use strict; use warnings; use Carp; sub new { my $class = shift; my $self = {}; bless ($self, $class); return $self; } ############################################################################## # # Constant OWL tags # ############################################################################## use constant RDF_RDF => 'rdf:RDF'; use constant RDF_TYPE => 'rdf:type'; use constant OWL_ONTOLOGY => 'owl:Ontology'; use constant OWL_CLASS => 'owl:Class'; use constant RDFS_LABEL => 'rdfs:label'; use constant RDFS_COMMENT => 'rdfs:comment'; use constant RDFS_SUBCLASSOF => 'rdfs:subClassOf'; use constant RDF_RESOURCE => 'rdf:resource'; use constant OWL_SOMEVALUESFROM => 'owl:someValuesFrom'; use constant OWL_ONPROPERTY => 'owl:onProperty'; use constant OWL_RESTRICTION => 'owl:Restriction'; use constant OWL_OBJECT_PROPERTY => 'owl:ObjectProperty'; use constant DISJOINT_WITH => 'owl:disjointWith'; use constant RDFS_SUBPROPERTYOF => 'rdfs:subPropertyOf'; # # oboInOwl # use constant OBOINOWL_HAS_DATE => 'oboInOwl:hasDate'; use constant OBOINOWL_HAS_DEFAULT_NAME_SPACE => 'oboInOwl:hasDefaultNamespace'; use constant OBOINOWL_SUBSET => 'oboInOwl:Subset'; use constant OBOINOWL_HAS_DEFINITION => 'oboInOwl:hasDefinition'; use constant OBOINOWL_DEFINITION => 'oboInOwl:Definition'; use constant OBOINOWL_HAS_DBXREF => 'oboInOwl:hasDbXref'; use constant OBOINOWL_DBXREF => 'oboInOwl:DbXref'; use constant OBOINOWL_HAS_URI => 'oboInOwl:hasURI'; use constant OBOINOWL_IN_SUBSET => 'oboInOwl:inSubset'; use constant OBOINOWL_SYNONYM => 'oboInOwl:Synonym'; use constant OBOINOWL_HAS_EXACT_SYNONYM => 'oboInOwl:hasExactSynonym'; use constant OBOINOWL_HAS_BROAD_SYNONYM => 'oboInOwl:hasBroadSynonym'; use constant OBOINOWL_HAS_NARROW_SYNONYM => 'oboInOwl:hasNarrowSynonym'; use constant OBOINOWL_HAS_RELATED_SYNONYM => 'oboInOwl:hasRelatedSynonym'; use constant OBOINOWL_HAS_ALTERNATIVE_ID => 'oboInOwl:hasAlternativeId'; use constant OBOINOWL_REPLACED_BY => 'oboInOwl:replacedBy'; use constant OBOINOWL_CONSIDER => 'oboInOwl:consider'; use constant OBOINOWL_HAS_NAMESPACE => 'oboInOwl:hasNamespace'; # # contexts # use constant CLASS_CONTEXT => 'rdf:RDFowl:Class'; use constant CLASS_XREF_LABEL => 'rdf:RDFowl:ClassoboInOwl:hasDbXrefoboInOwl:DbXrefrdfs:label'; use constant CLASS_XREF => 'rdf:RDFowl:ClassoboInOwl:hasDbXrefoboInOwl:DbXref'; use constant CLASS_DEF_DBXREF_LABEL => 'rdf:RDFowl:ClassoboInOwl:hasDefinitionoboInOwl:DefinitionoboInOwl:hasDbXrefoboInOwl:DbXrefrdfs:label'; use constant CLASS_DEF_DBXREF => 'rdf:RDFowl:ClassoboInOwl:hasDefinitionoboInOwl:DefinitionoboInOwl:hasDbXrefoboInOwl:DbXref'; use constant PROPERTY_XREF_LABEL => 'rdf:RDFowl:ObjectPropertyoboInOwl:hasDbXrefoboInOwl:DbXrefrdfs:label'; use constant PROPERTY_XREF => 'rdf:RDFowl:ObjectPropertyoboInOwl:hasDbXrefoboInOwl:DbXref'; use constant PROP_DEF_DBXREF_LABEL => 'rdf:RDFowl:ObjectPropertyoboInOwl:hasDefinitionoboInOwl:DefinitionoboInOwl:hasDbXrefoboInOwl:DbXrefrdfs:label'; use constant PROP_DEF_DBXREF => 'rdf:RDFowl:ObjectPropertyoboInOwl:hasDefinitionoboInOwl:DefinitionoboInOwl:hasDbXrefoboInOwl:DbXref'; use constant EXACT_SYNONYM_LABEL => 'rdf:RDFowl:ClassoboInOwl:hasExactSynonymoboInOwl:Synonymrdfs:label'; use constant EXACT_SYNONYM => 'rdf:RDFowl:ClassoboInOwl:hasExactSynonymoboInOwl:Synonym'; use constant BROAD_SYNONYM_LABEL => 'rdf:RDFowl:ClassoboInOwl:hasBroadSynonymoboInOwl:Synonymrdfs:label'; use constant BROAD_SYNONYM => 'rdf:RDFowl:ClassoboInOwl:hasBroadSynonymoboInOwl:Synonym'; use constant NARROW_SYNONYM_LABEL => 'rdf:RDFowl:ClassoboInOwl:hasNarrowSynonymoboInOwl:Synonymrdfs:label'; use constant NARROW_SYNONYM => 'rdf:RDFowl:ClassoboInOwl:hasNarrowSynonymoboInOwl:Synonym'; use constant RELATED_SYNONYM_LABEL => 'rdf:RDFowl:ClassoboInOwl:hasRelatedSynonymoboInOwl:Synonymrdfs:label'; use constant RELATED_SYNONYM => 'rdf:RDFowl:ClassoboInOwl:hasRelatedSynonymoboInOwl:Synonym'; use constant SYNONYM_DBXREF_LABEL => 'SYNONYM_DBXREF_LABEL'; use constant SYNONYM_DBXREF => 'SYNONYM_DBXREF'; # # Globals ;-) # my %data_current_tag; # for gathering the chars stream my $result; # The ontology my $count = 0; # count terms my $tag = ""; # current tag my $parent_tag = ""; # parent tag my $grant_parent_tag = ""; # grant parent tag my $great_parent_tag = ""; # great parent tag my $current_term_id; # current term ID my $relationship_type_id; my $def_char = 0; # defintion characters streamed my $current_relationship_type_id; # current relationship ID my $attr = ""; # current relationship my $current_line = 0; # current line in the parsed file my $is_metadata = 0; # if the element is aprt of the metadata (e.g. oboInOwl:DbXref) my @dbxref = (); # current dbxrefs my $owl_ontology_tag = 0; # inside the ontology data my $owl_class_tag = 0; # Am I parsing a class? my $owl_object_property_tag = 0; # Am I parsing a property? my $oboinowl_has_definition_tag = 0; # my $oboinowl_definition_tag = 0; # Am I parsing a definition chunk? my $oboinowl_synonym_tag = 0; # Am I parsing a synonym chunk? my $type_of_synonym; my $whitin_a_synonym = 0; =head2 work Usage - $OWLParser->work($owl_file_path) Returns - the parsed OWL ontology Args - the OWL file to be parsed Function - parses an OWL file (oboInOwl mapping) =cut sub work { my $self = shift; $self->{OWL_FILE} = shift if (@_); $result = OBO::Core::Ontology->new(); # # Stream-based processing # my $my_parser = new XML::Parser(); $my_parser->setHandlers( #Init => \&init, Start => \&startElement, End => \&endElement, Char => \&characterData #Default => \&default, #Final => \&final ); $my_parser->parsefile($self->{OWL_FILE}); open (OWL_FILE, $self->{OWL_FILE}) || croak "The OWL file cannot be opened: $!"; close OWL_FILE; return $result; } sub init { my $e = $_[0]; #print "autogenerated-by: $0\n"; } sub startElement { my( $parseinst, $element, %attrs ) = @_; $tag = $element; SWITCH: { $current_line = $parseinst->current_line(); $is_metadata = 0; if ($tag eq OWL_ONTOLOGY) { $parent_tag = $parseinst->current_element(); $owl_ontology_tag = 1; last SWITCH; } if ($tag eq OBOINOWL_HAS_DATE) { $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq OBOINOWL_HAS_DEFAULT_NAME_SPACE) { $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq OWL_CLASS) { my $term; $current_term_id = $2, $is_metadata = (defined $3)?1:0 if ($attrs{"rdf:about"} =~ m/.*\#((\w*_\w*\d*)|(\w*))$/); # Ontology terms or Metadata if ($current_term_id) { my $obo_like_id = owl_id2obo_id($current_term_id); $term = $result->get_term_by_id($obo_like_id); # does this term is already in the ontology? if (!defined $term){ $term = OBO::Core::Term->new(); # if not, create a new term $term->id($obo_like_id); $result->add_term($term); # add it to the ontology } elsif (defined $term->def()->text() && $term->def()->text() ne "") { # the term is already in the ontology since it has a definition! (maybe empty?) croak "The term with id '", $obo_like_id, "' is duplicated in the OWL file."; } } $parent_tag = $parseinst->current_element(); $owl_class_tag = 1; last SWITCH; } if ($tag eq OBOINOWL_HAS_NAMESPACE) { $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq RDFS_COMMENT) { $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq RDFS_LABEL) { $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq RDFS_SUBCLASSOF){ if (defined $attrs{"rdf:resource"} && $attrs{"rdf:resource"} =~ m/.*\#((\w*_\w*\d*)|(ObsoleteClass)|(\w*))$/) { if ($3) { # ObsoleteClass my $term = $result->get_term_by_id($current_term_id); $term->is_obsolete(1); } else { my $term = $result->get_term_by_id($current_term_id); my $rel = OBO::Core::Relationship->new(); my $target_id = $2; $target_id = owl_id2obo_id($target_id); $rel->id($term->id()."_"."is_a"."_".$target_id); $rel->type("is_a"); my $target = $result->get_term_by_id($target_id); # does this term is already in the ontology? if (!defined $target) { $target = OBO::Core::Term->new(); # if not, create a new term $target->id($target_id); $result->add_term($target); } $rel->link($term, $target); $result->add_relationship($rel); } } $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq DISJOINT_WITH){ if (defined $attrs{"rdf:resource"} && $attrs{"rdf:resource"} =~ m/.*\#((\w*_\w*\d*)|(\w*))$/) { if ($2) { my $disjoint_term_id = $2; my $term = $result->get_term_by_id($current_term_id); $term->disjoint_from(owl_id2obo_id($disjoint_term_id)); } } $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq OBOINOWL_DBXREF) { $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq OBOINOWL_HAS_DEFINITION) { $parent_tag = $parseinst->current_element(); $oboinowl_has_definition_tag = 1; last SWITCH; } if ($tag eq OBOINOWL_DEFINITION) { $parent_tag = $parseinst->current_element(); $oboinowl_definition_tag = 1; last SWITCH; } if ($tag eq OBOINOWL_SYNONYM) { $parent_tag = $parseinst->current_element(); $oboinowl_synonym_tag = 1; last SWITCH; } if ($tag eq OBOINOWL_HAS_EXACT_SYNONYM) { $parent_tag = $parseinst->current_element(); $whitin_a_synonym = 1; last SWITCH; } if ($tag eq OBOINOWL_HAS_BROAD_SYNONYM) { $parent_tag = $parseinst->current_element(); $whitin_a_synonym = 1; last SWITCH; } if ($tag eq OBOINOWL_HAS_NARROW_SYNONYM) { $parent_tag = $parseinst->current_element(); $whitin_a_synonym = 1; last SWITCH; } if ($tag eq OBOINOWL_HAS_RELATED_SYNONYM) { $parent_tag = $parseinst->current_element(); $whitin_a_synonym = 1; last SWITCH; } if ($tag eq OWL_OBJECT_PROPERTY && !$owl_class_tag) { my $type; $current_relationship_type_id = $3 if ($attrs{"rdf:about"} =~ m/.*\#((ObsoleteProperty)|(.*))$/); # Ontology terms or Metadata if ($current_relationship_type_id) { $type = $result->get_relationship_type_by_id($3); # does this relationship type is already in the ontology? if (!defined $type){ $type = OBO::Core::RelationshipType->new(); # if not, create a new type $type->id($3); $result->add_relationship_type($type); # add it to the ontology } elsif (defined $type->def()->text() && $type->def()->text() ne "") { # the type is already in the ontology since it has a definition! (maybe empty?) croak "The relationship type with id '", $3, "' is duplicated in the OWL file."; } $owl_object_property_tag = 1; } $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq OWL_OBJECT_PROPERTY && $owl_class_tag && $owl_class_tag) { # e.g. relationship: participates_in $relationship_type_id = $1 if ($attrs{"rdf:about"} =~ m/.*\#(.*)$/); $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq OWL_SOMEVALUESFROM && $owl_class_tag && $relationship_type_id) { my $target_term_id = $1 if ($attrs{"rdf:resource"} =~ m/.*\#(.*)$/); $target_term_id = owl_id2obo_id($target_term_id); my $term = $result->get_term_by_id($current_term_id); my $id = $term->id()."_".$relationship_type_id."_".$target_term_id; my $rel = OBO::Core::Relationship->new(); $rel->id($id); $rel->type($relationship_type_id); my $target = $result->get_term_by_id($target_term_id); # does this term is already in the ontology? if (!defined $target) { $target = OBO::Core::Term->new(); # if not, create a new term $target->id($target_term_id); $result->add_term($target); } $rel->link($term, $target); $result->add_relationship($rel); $relationship_type_id = undef; $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq RDFS_SUBPROPERTYOF){ if (defined $attrs{"rdf:resource"} && $attrs{"rdf:resource"} =~ m/.*\#(.*)$/) { my $target_id = $1; if ($target_id) { my $current_relationship_type_type = $result->get_relationship_type_by_id($current_relationship_type_id); my $rel = OBO::Core::Relationship->new(); $rel->id($current_relationship_type_type->id()."_"."is_a"."_".$target_id); $rel->type("is_a"); my $target = $result->get_relationship_type_by_id($target_id); # does this relationship type is already in the ontology? if (!defined $target) { $target = OBO::Core::RelationshipType->new(); # if not, create a new relationship type $target->id($target_id); $result->add_relationship_type($target); } $rel->link($current_relationship_type_type, $target); $result->add_relationship($rel); } } $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq OBOINOWL_HAS_ALTERNATIVE_ID) { $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq OBOINOWL_SUBSET) { if (defined $attrs{"rdf:about"}) { my @ss = split(/\//, $attrs{"rdf:about"}); my $ss = $ss[$#ss]; $data_current_tag{"subsets_and_comments"} .= $ss." " if ($ss); # WHITESPACE: workaround to have a separation between the subset name and its comment } $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq OBOINOWL_IN_SUBSET) { if (defined $attrs{"rdf:resource"}) { my @ss = split(/\//, $attrs{"rdf:resource"}); my $ss = $ss[$#ss]; if ($ss) { my $term = $result->get_term_by_id($current_term_id); $term->subset($ss); } } $parent_tag = $parseinst->current_element(); last SWITCH; } if ($tag eq RDF_TYPE && $owl_object_property_tag) { # TransitiveProperty et al. if (defined $attrs{"rdf:resource"} && $attrs{"rdf:resource"} =~ m/.*\#(.*)$/) { my $current_relationship_type = $result->get_relationship_type_by_id($current_relationship_type_id); if ($1 eq "TransitiveProperty") { $current_relationship_type->is_transitive(1); } elsif ($1 eq "SymmetricProperty") { $current_relationship_type->is_symmetric(1); } } $parent_tag = $parseinst->current_element(); last SWITCH; } } } sub characterData { my ($parseinst, $data) = @_; return unless $tag; my $bk = $data; my $current_term; my $current_relationship_type; if ($owl_class_tag) { # if we are parsing a class (no metadata elements like DbXref) $current_term = $result->get_term_by_id($current_term_id); } elsif ($owl_object_property_tag) { $current_relationship_type = $result->get_relationship_type_by_id($current_relationship_type_id); } $data =~ s/\n|\t|\r|\\//g; return unless $data; my $context = join("", $parseinst->context()); SWITCH : { # # Ontology data # if ($parent_tag eq OWL_ONTOLOGY) { if ($tag eq OBOINOWL_HAS_DATE) { $data_current_tag{"has_date"} .= $data; last SWITCH; } if ($tag eq OBOINOWL_HAS_DEFAULT_NAME_SPACE) { $data_current_tag{"default_name_space"} .= $data; last SWITCH; } if ($tag eq RDFS_COMMENT) { $data_current_tag{"comment"} .= $data; last SWITCH; } last SWITCH; } if ($parent_tag eq OBOINOWL_SUBSET) { if ($tag eq RDFS_COMMENT) { $data_current_tag{"subsets_and_comments"} .= $data; last SWITCH; } last SWITCH; } # # Classes # if ($parent_tag eq OWL_CLASS) { if ($tag eq RDFS_LABEL) { $data_current_tag{"name"} .= $data; last SWITCH; } if ($tag eq OBOINOWL_HAS_NAMESPACE) { $current_term->namespace($data); last SWITCH; } if ($tag eq RDFS_COMMENT) { $data_current_tag{"comment"} .= $data; last SWITCH; } if ($tag eq OBOINOWL_HAS_ALTERNATIVE_ID) { $data_current_tag{"alt_id"} .= $data; last SWITCH; } if ($tag eq OBOINOWL_REPLACED_BY) { $data_current_tag{"replaced_by"} .= $data; last SWITCH; } if ($tag eq OBOINOWL_CONSIDER) { $data_current_tag{"consider"} .= $data; last SWITCH; } last SWITCH; } if (($parent_tag eq OBOINOWL_DEFINITION) && ($tag eq RDFS_LABEL)) { # is it needed to check that '$tag eq RDFS_LABEL' ? $data_current_tag{"def"} .= $data, $def_char = 1 if ($owl_class_tag); $data_current_tag{"def"} .= $data, $def_char = 1 if ($owl_object_property_tag); last SWITCH; } if ($context eq CLASS_DEF_DBXREF_LABEL){ $data_current_tag{+CLASS_DEF_DBXREF_LABEL} .= $data; last SWITCH; } if ($context eq PROP_DEF_DBXREF_LABEL){ $data_current_tag{+PROP_DEF_DBXREF_LABEL} .= $data; last SWITCH; } if ($context eq CLASS_XREF_LABEL) { $data_current_tag{+CLASS_XREF_LABEL} .= $data; last SWITCH; } if ($context eq PROPERTY_XREF_LABEL) { $data_current_tag{+PROPERTY_XREF_LABEL} .= $data; last SWITCH; } if (($parent_tag eq OBOINOWL_SYNONYM) && ($tag eq RDFS_LABEL)) { $type_of_synonym = uc($1) if ($context =~ /(Exact|Broad|Narrow|Related)/); $data_current_tag{$type_of_synonym} .= $data; last SWITCH; } if (($context =~ /rdf:RDF(owl:Class|owl:ObjectProperty)oboInOwl:has(Exact|Broad|Narrow|Related)SynonymoboInOwl:Synonym/) && ($tag eq RDFS_LABEL)){ $data_current_tag{"xref"} .= $data; last SWITCH; } # # Properties # if ($parent_tag eq OWL_OBJECT_PROPERTY) { if ($tag eq RDFS_LABEL) { $current_relationship_type->name($data); last SWITCH; } if ($tag eq OBOINOWL_HAS_NAMESPACE) { $current_relationship_type->namespace($data); last SWITCH; } if ($tag eq RDFS_COMMENT) { $current_relationship_type->comment($data); last SWITCH; } if ($tag eq OBOINOWL_HAS_ALTERNATIVE_ID) { $data_current_tag{"alt_id"} .= $data; last SWITCH; } if ($tag eq OBOINOWL_REPLACED_BY) { $data_current_tag{"replaced_by"} .= $data; last SWITCH; } if ($tag eq OBOINOWL_CONSIDER) { $data_current_tag{"consider"} .= $data; last SWITCH; } last SWITCH; # TODO Wait until the mapping is more stable, then implement: union, intersection, transitive over, ... } } # SWITCH } sub endElement { my( $parseinst, $element ) = @_; $tag = undef; my $current_term; my $current_relationship_type; if ($owl_class_tag && $current_term_id) { # if we are parsing a class (no metadata elements like DbXref) $current_term = $result->get_term_by_id($current_term_id); } elsif ($owl_object_property_tag && $current_relationship_type_id) { $current_relationship_type = $result->get_relationship_type_by_id($current_relationship_type_id); } my $context = join("", $parseinst->context()); SWITCH: { if ($element eq OWL_ONTOLOGY) { $owl_ontology_tag = 0; last SWITCH; } if ($element eq OBOINOWL_HAS_DATE) { my $date = $data_current_tag{"has_date"}; $result->date($date) if (defined $date); $data_current_tag{"has_date"} = undef; last SWITCH; } if ($element eq OBOINOWL_HAS_DEFAULT_NAME_SPACE) { my $default_namespace = $data_current_tag{"default_name_space"}; $result->default_namespace($default_namespace) if (defined $default_namespace); $data_current_tag{"default_name_space"} = undef; last SWITCH; } if ($element eq RDFS_LABEL && $context eq CLASS_CONTEXT) { $current_term->name($data_current_tag{"name"}); $data_current_tag{"name"} = undef; last SWITCH; } if ($element eq OWL_CLASS) { $owl_class_tag = 0; # not parsing a class anymore last SWITCH; } if ($element eq OWL_OBJECT_PROPERTY) { $owl_object_property_tag = 0; # not parsing a property anymore last SWITCH; } if ($element eq OBOINOWL_HAS_DEFINITION) { $oboinowl_has_definition_tag = 0; last SWITCH; } if ($element eq OBOINOWL_DEFINITION && $def_char) { my $def = char_hex2ascii($data_current_tag{"def"}); $def =~ s/"/\\"/g; $current_term->def()->text($def) if ($owl_class_tag); $current_relationship_type->def()->text($def) if ($owl_object_property_tag); $oboinowl_definition_tag = 0; $def_char = 0; $data_current_tag{"def"} = undef; last SWITCH; } if ($context eq CLASS_DEF_DBXREF) { my $label = $data_current_tag{+CLASS_DEF_DBXREF_LABEL}; if ($label) { $label = "http:".char_hex2ascii($1) if ($label =~ /URL:http%3A%2F%2F(.*)/); $current_term->def()->dbxref_set_as_string("[".$label."]") if (defined $label); } $data_current_tag{+CLASS_DEF_DBXREF_LABEL} = undef; last SWITCH; } if ($context eq PROP_DEF_DBXREF) { my $label = $data_current_tag{+PROP_DEF_DBXREF_LABEL}; if ($label) { $label = "http:".char_hex2ascii($1) if ($label =~ /URL:http%3A%2F%2F(.*)/); $current_relationship_type->def()->dbxref_set_as_string("[".$label."]") if (defined $label); } $data_current_tag{+PROP_DEF_DBXREF_LABEL} = undef; last SWITCH; } if ($context eq CLASS_XREF) { my $label = $data_current_tag{+CLASS_XREF_LABEL}; $current_term->xref_set_as_string($label) if (defined $label); $data_current_tag{+CLASS_XREF_LABEL} = undef; last SWITCH; } if ($context eq PROPERTY_XREF) { my $label = $data_current_tag{+PROPERTY_XREF_LABEL}; $current_relationship_type->xref_set_as_string($label) if (defined $label); $data_current_tag{+PROPERTY_XREF_LABEL} = undef; last SWITCH; } if ($element eq RDFS_COMMENT) { my $comment = $data_current_tag{"comment"}; my $subsets_and_comment = $data_current_tag{"subsets_and_comments"}; if (defined $comment) { if ($owl_class_tag) { $current_term->comment($comment); } elsif ($owl_object_property_tag) { $current_relationship_type->comment($comment); } elsif ($owl_ontology_tag) { $result->remark($comment); } } elsif (defined $subsets_and_comment) { $result->subsets($subsets_and_comment); } $data_current_tag{"comment"} = undef; $data_current_tag{"subsets_and_comments"} = undef; last SWITCH; } if ($element eq OBOINOWL_HAS_ALTERNATIVE_ID) { my $alt_id = $data_current_tag{"alt_id"}; $current_term->alt_id($alt_id) if (defined $alt_id); $data_current_tag{"alt_id"} = undef; last SWITCH; } if ($element eq OBOINOWL_REPLACED_BY) { my $replaced_by = $data_current_tag{"replaced_by"}; $current_term->alt_id($replaced_by) if (defined $replaced_by); $data_current_tag{"replaced_by"} = undef; last SWITCH; } if ($element eq OBOINOWL_CONSIDER) { my $consider = $data_current_tag{"consider"}; $current_term->alt_id($consider) if (defined $consider); $data_current_tag{"consider"} = undef; last SWITCH; } if ($element eq OBOINOWL_SYNONYM) { # && $context =~ /rdf:RDFowl:ClassoboInOwl:has(Exact|Broad|Narrow|Related)SynonymoboInOwl:Synonym/ my $ref_label = $data_current_tag{"xref"}; my $data_syn = $data_current_tag{$type_of_synonym}; my $sref = ($ref_label)?"[".$ref_label."]":"[]"; if (defined $data_syn) { # Future improvement: get the 'synonym type name' and process it $current_term->synonym_as_string($data_syn, $sref, $type_of_synonym) if (defined $current_term); $current_relationship_type->synonym_as_string($data_syn, $sref, $type_of_synonym) if (defined $current_relationship_type); } $data_current_tag{$type_of_synonym} = undef; $data_current_tag{"xref"} = undef; last SWITCH; } if ($element eq OBOINOWL_HAS_EXACT_SYNONYM) { $whitin_a_synonym = 0; last SWITCH; } if ($element eq OBOINOWL_HAS_BROAD_SYNONYM) { $whitin_a_synonym = 0; last SWITCH; } if ($element eq OBOINOWL_HAS_NARROW_SYNONYM) { $whitin_a_synonym = 0; last SWITCH; } if ($element eq OBOINOWL_HAS_RELATED_SYNONYM) { $whitin_a_synonym = 0; last SWITCH; } } } =head2 owl_id2obo_id Usage - $obj->owl_id2obo_id($term) Returns - the ID for OBO representation. Args - the OWL-type ID. Function - Transform an OWL-type ID into an OBO-type one. E.g. CCO_I1234567 -> CCO:I1234567 =cut sub owl_id2obo_id { confess "owl_id2obo_id: Invalid argument: '", $_[0], "'", if ($_[0] !~ /_/); $_[0] =~ s/_/:/; return $_[0]; } =head2 char_hex_http Usage - $obj->char_hex_http($seq) Returns - the sequence with the hexadecimal representation for the http special characters Args - the sequence of characters Function - Transforms a http character to its equivalent one in hexadecimal. E.g. : -> %3A =cut sub char_hex2ascii { my $param = $_[0]; $param =~ s/%3A/:/g; $param =~ s/%3B/;/g; $param =~ s/%3C//g; $param =~ s/%3F/\?/g; #number sign # 23 # --> # # --> # #dollar sign $ 24 $ --> $ $ --> $ #percent sign % 25 % --> % % --> % $param =~ s/%2F/\//g; $param =~ s/%26/&/g; return $param; } 1;