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

  XML::RelaxNG::Compact::DataModel -  RelaxNG Compact L<http://relaxng.org/compact-tutorial-20030326.html> schema  expressed in perl

VERSION

Version 0.01

DESCRIPTION

 This is a user's guide module for documentation only. It describes the perlish expression of the  RelaxNG Compact schema. 
 Some limitations are: 
    
  • there is no datatyping,

  • there is no support for minLength,maxLength xsd:string constraints, although conditional logic is supported

  • there is no support for annotations

  • support for includes and inherit are provided by the data model developer, means you can split your model in different packages and inherit it. Just remember that PXB deals with references to hashes and arrays. See below.

 Everything else can be expressed by perl constructs and will be supported by the created API.
 Every element from the schema can be expressed as perl hash reference:
  Where each <xxxx-definition> can be expressed in EBNF  as
   In the attributes definition the xmlns attribute is reserved for the namespace prefix.
 This name must be registered within Namespace class in order to provide some level of validation. 
 This constraint will be fixed in future releases.
 Its recommended to have unique C<id> attribute in each element, it will allow to utilize mapping by C<id> for the complex element types.
 
    There is some conditional logic allowed for attributes. An attribute value can be scalar which stays 
 for C<scalar> string or enumerated list of the allowed names. The list of  elements 
 is represented as array reference. The choice between several possible  elements 
 is introduced as array reference to the list and having multiple  elements of one kind is represented 
 as reference to array consisted with single element variable of that kind.

For example:

elements => [parameter => $parameter] - defines single parameter sub-element
elements => [parameter => [$parameter]] - defines list of parameter sub-elements
elements => [parameters => [$parameters, $select_parameters]] - defines choice between two single parameters sub-elements of different type
elements => [datum => [[$pinger_datum],[$result_datum]] ] - defines choice between two lists of datum sub-elements of different type
    In C<elements-definition> the third member is an optional conditional statement which represents validation rule.
 For example C<unless:value> conditional statement will be translated into the perl's conditional statement 
 C<< && !($self->value) >> where value must be registered attribute or sub-element name and this 
 condition will be placed in every piece of code where perl object is serialized into the XML DOM object or from it. 

 
 B<Note:> You have to define element bottom-to-top in order for them to "know" about each other.
   

SYNOPSIS

      ## for example lets define some RelaxNG schema  in Compact notation and then express it as perl data structure
      #   this is a base schema from the L<http://ogf.org/schema/network/topology/base> namespace
      #
      # start =
      #  (
      #          element nmwg:message {
      #                  MessageContent
      #          } 
      #  )
      #
      #  MessageContent =
      #       Identifier? & 
      #       MessageIdentifierRef? &
      #       Type &
      #       Parameters? &                        
      #       (
      #               Metadata  
      #       )+
      #
      #  Identifier = attribute id { xsd:string }
      #
      #  IdReference =    attribute idRef { xsd:string }
      #      
      #  Type = attribute type { xsd:string }   
      #  MetadataIdentifierRef = attribute metadataIdRef { xsd:string }
      #
      #  MessageIdentifierRef =  attribute messageIdRef { xsd:string }
      # 
      # Metadata = 
      #    element nmwg:metadata {
      #           (
      #                   Identifier &
      #                   MetadataIdentifierRef? &
      #                   MetadataContent
      #           )
      #    }
      #
      # MetadataBlock =
      #    Parameters?
      #
      # MetadataContent = 
      #  (
      #    MetadataBlock             
      #  ) &         
      #  EventType? &
      #
      # EventType =  element nmwg:eventType { xsd:string }      
      # 
      #  Parameters = 
      #    element nmwg:parameters {
      #             ParametersContent
      #    }
      #  
      # ParametersContent =      
      #   Identifier &
      #   Parameter+
      #  
      # Parameter =   element nmwg:parameter { 
      #         attribute name { 
      #                          "count" | "packetInterval" | "endTime"| 
      #                          "packetSize" | "ttl" |  "startTime" | 
      #                          "valueUnits"  
      #                        } &
      #         (
      #                 attribute value { text } |
      #                 text
      #         )
      #   }
 

 
     $parameter =  {attrs  => {name => 'enum:count,packetInterval,packetSize,ttl,valueUnits,startTime,endTime',  
                               value => 'scalar', 
                               xmlns => 'nmwg'},
                    elements => [],
                    text => 'unless:value',
                 };              
     $parameters =  {attrs  => {id => 'scalar',   
                                xmlns => 'nmwg'},
                     elements => [
                                    [parameter => [$parameter]], 
                              
                                ], 
                   };
   
  
     $metadata = {attrs  => {id => 'scalar', metadataIdRef => 'scalar',
                             xmlns => 'nmwg'},
                  elements => [
                                 [parameters =>   $parameters],
                                 [eventType  =>  'text'] 
                            ], 
                }; 

     $message  = {attrs  => {id => 'scalar', type => 'scalar', xmlns => 'nmwg'}, 
                  elements => [ 
                                 [parameters =>  [$parameters]],
                                 [metadata => [$metadata]], 
                                 [data     => [$data]]
                              ], 
                 };
     
     ## this is it, as you can see it takes much less code to express the same RelaxNG compact schema 
     ## and of course that means even less code in case of  XML schema
    
     

SQL MAPPING

      After ( or at the time of ) defining your elements  you can set your sql mapping.
      Actually, it could be mapping to any external data model.  
      Lets see how we can map parameters from C<parameter> element into some fields from some SQL DB table
   
      # take C<$parameter> element from the previous example 

DEVELOPING DATA MODELS

      The best design pattern would be writing your data model by following your schema design. 
  Create DataModel.pm package for the base schema and export all necessary 
  data structures and then somewhere in the building script add any extra sql mapping or even redefine some elements by replacing particular 
  element definitions with new data structure.  Of course you can mix elements with the same names from the different namespaces,
  just name them differently but  it would be easier to define them in separate data model packages. 
      
  

AUTHOR

    Maxim Grigoriev, maxim at fnal_gov

LICENSE

   Fermitools license (open source, modified BSD type), see   L<http://fermitools.fnal.gov/about/terms.html>

COPYRIGHT

  Copyright (C) 2007-2008 by Fermitools, Fermilab

1 POD Error

The following errors were encountered while parsing the POD:

Around line 65:

Non-ASCII character seen before =encoding in '’'[''. Assuming CP1252