The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

MOBYXSLT - CommonSubs using XSLT

WHY

Because huge XML message parsing with XML::Dom take too much time. xsltproc is a binary very very efficient to parse huge files.

TO BE EDITED

    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

SYNOPSIS

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());

}

GLOBALS

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

DESCRIPTION

Note: many functions have same names as those from MOBY::CommonSubs

function getInputs

 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

function getInputID

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

function getArticles

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

function getCollectedSimples

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

function getCrossReferences

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

function getProvisionInformation

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

function getObjectHasaElements

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

function getObjectType

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

function getObjectName

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

function getObjectNamespace

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

function getObjectContent

 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

function getObjectXML

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

function getObjectId

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

function getParameter

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

function getNodeContentWithArticle

 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      : 

function isSimpleArticle

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

function isCollectionArticle

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

function isSecondaryArticle

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

function _AnalyseSimple

 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

simpleResponse (stolen from MOBY::CommonSubs)

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.

collectionResponse (stolen from MOBY::CommonSubs)

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).

complexResponse (stolen from MOBY::CommonSubs)

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

responseHeader (stolen from MOBY::CommonSubs)

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'>

encodeException (stolen from MOBY::CommonSubs)

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>

responseFooter (stolen from MOBY::CommonSubs)

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>

function _IsCollection

 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

function _IsSimple

 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

function _IsSecondary

 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

_rearrange (stolen from MOBY::CommonSubs)

function _AnalyseServiceNotes

 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