MOBYXSLT - CommonSubs using XSLT
Because huge XML message parsing with XML::Dom take too much time. xsltproc is a binary very very efficient to parse huge files.
Globals variables are defined in this package:
my $TMP_DIR = '/tmp/'; #Where your temporary files will be written my $XSLTPROC = '/usr/bin/xsltproc'; #Where your xsltproc binary is located my $XSL_SHEET = './parseMobyMessage.xsl'; #Where your xsltproc style-sheet is located
sub MonWebservice {
my ($caller, $message) = (@_);
my $moby_response;
my $service_name = 'MonWebservice';
#Message Parsing my ($service_notes,$ra_queries) = MOBYXSLT::getInputs($message); #Message Parsing
foreach my $query (@{$ra_queries}) { my $query_id = MOBYXSLT::getInputID($query);#Retrieve Query ID my @a_input_articles = MOBYXSLT::getArticles($query);#Retrieve articles
my ($fasta_sequences, $fasta_namespace, $fasta_id) = ('','','');
foreach my $input_article (@a_input_articles) { my ($article_name, $article) = @{$input_article};
if (MOBYXSLT::isSimpleArticle($article)) { my $object_type = MOBYXSLT::getObjectType($article);
if (IsTheCorrectType($object_type)) { $fasta_sequences = MOBYXSLT::getObjectContent($article); $fasta_namespace = MOBYXSLT::getObjectNamespace($article); $fasta_id = MOBYXSLT::getObjectId($article); } } elsif (MOBYXSLT::isCollectionArticle($article)) { }
elsif (MOBYXSLT::isSecondaryArticle($article)) { my ($param_name,$param_value) = MOBYXSLT::getParameter($article);#Retrieve parameters } }
###### #What you want to do with your data ######
my $cmd ="...";
system("$cmd");
######### #Send result #########
$moby_response .= MOBYXSLT::simpleResponse("<$output_object_type1>$out_data</$output_object_type1>", $output_article_name1, $query_id); }
return SOAP::Data->type( 'base64' => (MOBYXSLT::responseHeader(-authority => $auth_uri, -note => "Documentation about $service_name at $url_doc")) . $moby_response . MOBYXSLT::responseFooter());
}
my $TMP_DIR = '/tmp/'; #Where your temporary files will be written my $XSLTPROC = '/usr/bin/xsltproc'; #Where your xsltproc binary is located my $XSL_SHEET = './parseMobyMessage.xsl'; #Where your xsltproc style-sheet is located
Note: many functions have same names as those from MOBY::CommonSubs
Title : getInputs Usage : my ($servicenotes, $ra_queries) = getInputs($moby_message) Prerequisite : Function : Parse Moby message and build Perl structures to access for each query to their articles and objects. Returns : $servicenotes: Notes returned by service provider $ra_queries: ARRAYREF of all queries analysed in MOBY message Args : $moby_message: MOBY XML message Globals : $XSLTPROC: /path/to/xsltproc binary $XSL_SHEET: XSL Sheet for MobyMessage Parsing $TMP_DIR: /where
Title : getInputID Usage : my $query_id =getInputID($rh_query); Prerequisite : Function : Return query_id of a query from getInputs Returns : $query_id Args : $rh_query: query HASHREF structure from getInputs Globals : none
Title : getArticles Usage : my @a_input_articles =getArticles($rh_query); Prerequisite : Function : For a query from getInputs, retrieve list of articles represented by a ARRAYREF corresponding to REF(articleName, articlePerlStructure) Returns : @a_input_articles: ARRAY of articles ARRAYREF Args : $rh_query: query HASHREF structure from getInputs Globals : none
Title : getCollectedSimples Usage : my @a_simple_articles =getCollectedSimples($rh_collection_article); Prerequisite : Function : For a collection query from getArticles, retrieve list of simple articles Returns : @a_simple_articles: ARRAY of articles HASHREF Args : $rh_collection_article: collection article HASHREF structure from getArticles Globals : none
Title : getCrossReferences Usage : my @a_crossreferences =getCrossReferences($rh_simple_article); Prerequisite : Function : Takes a simple article structure (from getArticles or getCollectedSimples) and retrieve the list of crossreferences HASHREF Returns : @a_crossreferences: ARRAY of crossreferences HASHREF Args : $rh_simple_article: simple article HASHREF structure from getArticles or getCollectedSimples Globals : none
Title : getProvisionInformation Usage : my @a_pib =getProvisionInformation($rh_simple_article); Prerequisite : Function : Takes a simple article structure (from getArticles or getCollectedSimples) and retrieve the list of Provision Information HASHREF Returns : @a_pib: ARRAY of provisionInformation HASHREF Args : $rh_simple_article: simple article HASHREF structure from getArticles or getCollectedSimples Globals : none
Title : getObjectHasaElements Usage : my @a_hasa_elements =getObjectHasaElements($rh_simple_article); Prerequisite : Function : Takes a simple article structure (from getArticles or getCollectedSimples) and retrieve the list of "HASA" element HASHREF Returns : @a_hasa_elements: ARRAY of "HASA" element HASHREF Args : $rh_object: simple article HASHREF structure from getArticles or getCollectedSimples Globals : none
Title : getObjectType Usage : my $object_type =getObjectType($rh_object); Prerequisite : Function : Returns object MOBY class/type Returns : $object_type: object MOBY class/type Args : $rh_object: simple article (object) HASHREF structure from getArticles,getCollectedSimples or getObjectHasaElements Globals : none
Title : getObjectName Usage : my $object_name =getObjectName($rh_object); Prerequisite : Function : Returns object moby:articleName Returns : $object_name: moby:articleName Args : $rh_object: simple article (object) HASHREF structure from getArticles,getCollectedSimples or getObjectHasaElements Globals : none
Title : getObjectNamespace Usage : my $object_namespace =getObjectNamespace($rh_object); Prerequisite : Function : Returns object moby:namespace Returns : $object_name: moby:namespace Args : $rh_object: simple article (object) HASHREF structure from getArticles,getCollectedSimples or getObjectHasaElements Globals : none
Title : getObjectContent Usage : my $object_content =getObjectContent($rh_object); Prerequisite : Function : Returns object content (using HTML::Entities::decode) Warning: this content could contain emptylines if your objects contains Crossreferences or Hasa Elements ... Returns : $object_content: object content (decoded using HTML::Entities::decode) Args : $rh_object: simple article (object) HASHREF structure from getArticles,getCollectedSimples or getObjectHasaElements Globals : none
Title : getObjectXML Usage : my $object_xml =getObjectXML($rh_object); Prerequisite : Function : Returns full object moby:xml string Returns : $object_xml: object moby:xml string Args : $rh_object: simple article (object) HASHREF structure from getArticles,getCollectedSimples or getObjectHasaElements Globals : none
Title : getObjectId Usage : my $object_id =getObjectId($rh_object); Prerequisite : Function : Returns object moby:id Returns : $object_id: moby:id Args : $rh_object: simple article (object) HASHREF structure from getArticles,getCollectedSimples or getObjectHasaElements Globals : none
Title : getParameter Usage : my ($parameter_name,$parameter_value) =getParameter($rh_article); Prerequisite : Function : Returns parameter name an value for a Secondary aricle Returns : $parameter_name $parameter_value Args : $rh_article: secondary article HASHREF structure from getArticles Globals : none
Title : getNodeContentWithArticle Usage : my $content = getNodeContentWithArticle($rh_query, $article_type, $article_name) Prerequisite : Function : inside a mobyData bloc (structured in $rh_query), look for an article of a defined type (Simple, Collection or Parameter). Foreach matching article, search for an object named $article_name. If found, return its content. Returns : $content: content of article requested Args : $rh_query: query HASHREF structure from getInputs $article_type: 'Simple/Collection/Parameter' $article_name: attribute moby:articleName Globals :
Title : isSimpleArticle Usage : isSimpleArticle($rh_article) Prerequisite : Function : Test if an article is a moby:Simple Returns : $response: BOOLEAN Args : $rh_article: article HASHREF structure from getArticles Globals : none
Title : isCollectionArticle Usage : isCollectionArticle($rh_article) Prerequisite : Function : Test if an article is a moby:Collection Returns : $response: BOOLEAN Args : $rh_article: article HASHREF structure from getArticles Globals : none
Title : isSecondaryArticle Usage : isSecondaryArticle($rh_article) Prerequisite : Function : Test if articleType is moby:Parameter (secondary article) Returns : $response: BOOLEAN Args : $rh_article: article HASHREF structure from getArticles Globals : none
Title : _AnalyseSimple Usage : _AnalyseSimple($simple_bloc) Prerequisite : Function : Analyse a "Simple Bloc" from XSL transformation parsing Build a $rh_simple_article structure with fields: 'object_name' => moby:articleName 'object_type' => moby:Class 'object_namespace' => moby:namespace 'object_id' => moby:id 'object_content' => text content of simple article 'object_xml' => full xml content of article 'object_hasa' => ARRAYREF of hasa elements (each one is structured in a same structured hash (recursivity) 'object_crossreference' => ARRAYREF of crossreferences objects (each one is structured in a hash with fields 'type', 'id', 'namespace')
Returns : $rh_simple: article HASHREF Args : $simple_bloc: from parsing of a "simple" XSLT transformation Globals : none
name : simpleResponse function : wraps a simple article in the appropriate (mobyData) structure usage : $resp .= &simpleResponse($object, 'MyArticleName', $queryID); args : (in order) $object - (optional) a MOBY Object as raw XML $article - (optional) an articeName for this article $query - (optional, but strongly recommended) the queryID value for the mobyData block to which you are responding notes : as required by the API you must return a response for every input. If one of the inputs was invalid, you return a valid (empty) MOBY response by calling &simpleResponse(undef, undef, $queryID) with no arguments.
name : collectionResponse function : wraps a set of articles in the appropriate mobyData structure usage : return responseHeader . &collectionResponse(\@objects, 'MyArticleName', $queryID) . responseFooter; args : (in order) \@objects - (optional) a listref of MOBY Objects as raw XML $article - (optional) an articeName for this article $queryID - (optional, but strongly recommended) the mobyData ID to which you are responding notes : as required by the API you must return a response for every input. If one of the inputs was invalid, you return a valid (empty) MOBY response by calling &collectionResponse(undef, undef, $queryID).
name : complexResponse function : wraps a set of articles in the one mobyData structure usage : return responseHeader . &complexResponse(\@a_article_structures, $queryID) . responseFooter; args : (in order) \@a_article_structures - (optional) a listref of structured articles %h_article = ( article_type => 'collection/simple', article_content => 'MOBY XML formatted content', article_name => 'articleName attribut') $queryID - (optional, but strongly recommended) the mobyData ID to which you are responding =cut
sub complexResponse { my ($ra_data, $qID) = @_;
$ra_data ||= []; $qID ||= ''; unless ((ref($ra_data) =~ /array/i) && $ra_data->[0]) { # we're expecting an arrayref as input data,and it must not be empty return "<moby:mobyData moby:queryID='$qID'/>"; } my $moby_data_content = ''; foreach my $rh_data_block (@{$ra_data}) { my $article_name = $rh_data_block->{article_name}; my $article_content = $rh_data_block->{article_content};
if ($rh_data_block->{article_type} =~ /collection/i) { my $collection_content = "<moby:Collection moby:articleName='$article_name'>\n"; if ((ref($article_content) =~ /array/i) && $article_content->[0]) { foreach my $simple_element (@{$article_content}) { $collection_content .= "\t<moby:Simple>\n\t$simple_element\n\t</moby:Simple>\n"; } } else { $collection_content .= "\t<moby:Simple/>\n"; } $collection_content .= "</moby:Collection>\n";
$moby_data_content .= $collection_content;
} else { my $simple_content = "<moby:Simple moby:articleName='$article_name'>\n\t$article_content\n</moby:Simple>"; $moby_data_content .= $simple_content; } }
return "<moby:mobyData moby:queryID='$qID'>\n\t$moby_data_content\n</moby:mobyData>\n"; }
function: print the XML string of a MOBY response header +/- serviceNotes +/- Exceptions
usage:
responseHeader('illuminae.com')
responseHeader( -authority => 'illuminae.com', -note => 'here is some data from the service provider' -exception=>'an xml encoded exception string')
args: a string representing the service providers authority URI, OR a set of named arguments with the authority and the service provision notes which can include already xml encoded exceptions
caveat :
notes: returns everything required up to the response articles themselves. i.e. something like:
<?xml version='1.0' encoding='UTF-8'?> <moby:MOBY xmlns:moby='http://www.biomoby.org/moby'> <moby:Response moby:authority='http://www.illuminae.com'>
function: wraps a Biomoby Exception with all its parameters into the appropiate MobyData structure
usage:
encodeException( -refElement => 'refers to the queryID of the offending input mobyData', -refQueryID => 'refers to the articleName of the offending input Simple or Collection' -severity=>'error' -exceptionCode=>'An error code ' -exceptionMessage=>'a human readable description for the error code')
args:the different arguments required by the mobyException API severity can be either error, warning or information valid error codes are decribed on the biomoby website
notes: returns everything required to use for the responseHeader:
<moby:mobyException moby:refElement='input1' moby:refQueryID='1' moby:severity =''> <moby:exceptionCode>600</moby:exceptionCode> <moby:exceptionMessage>Unable to execute the service</moby:exceptionMessage> </moby:mobyException>
name : responseFooter function : print the XML string of a MOBY response footer usage : return responseHeader('illuminae.com') . $DATA . responseFooter; notes : returns everything required after the response articles themselves i.e. something like:
</moby:Response> </moby:MOBY>
Title : _IsCollection Usage : _IsCollection($article_type) Prerequisite : Function : Compares a string to string 'collection' Remove namespace 'moby:' from parameter string Case insensitive Returns : BOOLEAN Args : $articletype: a string Globals : none
Title : _IsSimple Usage : _IsSimple($article_type) Prerequisite : Function : Compares a string to string 'simple' Remove namespace 'moby:' from parameter string Case insensitive Returns : BOOLEAN Args : $articletype: a string Globals : none
Title : _IsSecondary Usage : _IsSecondary($article_type) Prerequisite : Function : Compares a string to string 'parameter' Remove namespace 'moby:' from parameter string Case insensitive Returns : BOOLEAN Args : $articletype: a string Globals : none
Title : _AnalyseServiceNotes Usage : _AnalyseServiceNotes($simple_bloc) Prerequisite : Function : Analyse a "Simple Bloc" from XSL transformation parsing Build a $rh_simple_article structure with fields: 'object_name' => moby:articleName 'object_type' => moby:Class 'object_namespace' => moby:namespace 'object_id' => moby:id 'object_content' => text content of simple article 'object_xml' => full xml content of article 'object_hasa' => ARRAYREF of hasa elements (each one is structured in a same structured hash (recursivity) 'object_crossreference' => ARRAYREF of crossreferences objects (each one is structured in a hash with fields 'type', 'id', 'namespace')
Returns : $services_notes: article HASHREF $ra_exceptions: article HASHREF Args : $service_notes_bloc: from parsing of a "serviceNotes" XSLT transformation Globals : none