6. Data Model (still continued...) What about complex types ? Lists, choice between different elements or choice between the elements with the same local name but from the different namespaces: For example: elements => [parameter => [$parameter]] - defines list of parameter elements elements => [parameter => $parameter] - defines single parameter element elements => [parameter => [$parameter, $other_parameter]] - defines choice between two single elements with different local names (for example nmwg:parameter and nmwg:otherParameter ) elements => [parameter => [[$ns1_parameter], [$ns2_parameter]] ] - defines choice between two lists of elements with the same local name but belonged to different namespaces DONE WITH DATA MODEL...
7. Building API Once your model is defined its very easy to create your API: use XML::RelaxNG::Compact::PXB; use POD::Credentials ; my $api_builder = XML::RelaxNG::Compact::PXB->new({ top_dir => "/home/joedoe/API", datatypes_root => "XMLTypes", nsregistry => { ’nsid1’ => ’http://some.org/nsURI’}, schema_version => "1.0", test_dir => "t", footer => POD::Credentials->new({author=> ’Joe Doe’}), }); $api_builder->buildAPI(‘myParameter’, $parameter); It will create package XMLTypes::v1_0::nsid1::MyParameter as: /home/joedoe/API/XMLTypes/v1_0/nsid1/MyParameter.pm Some helper classes and the test suit: /home/joedoe/API/t/XMLTypes::v1_0::nsid1::MyParameter.t /home/joedoe/API/t/conf/perlcriticrc /home/joedoe/API/t/conf/perltidyrc /home/joedoe/API/test.pl
8. All the goodies ( aka API introspection ) Every generated class has constructor with the same interface, it accepts single hash ref as an argument and every class implements the same set of methods. Every method in the class follows the same prototype. Every object can be initialized from the XML fragment ( scalar ), DOM object or reference to the hash. Of course it can be serialized back into the DOM or XML. It knows how to handle complex types. There are many XML schema where each element is identified by unique attribute named id . The generated API can build a map of such elements and supports addById, removeById to allow faster lookup for the multiple elements in the list. There is a special call named registerNamespaces for returning hash of the all namespaces registered for the root object Every element is mapped on the particular namespace by the namespace prefix. Example of API utilization , perldoc XMLTypes/v1_0/nsid1/MyParameter to see full list of calls : use XMLTypes::v1_0::nsid1::MyParameter; my $object = XMLTypes::v1_0::nsid1::MyParameter->new({ xml => ‘ <nsid1:myParameter xmlns:nsid1="http://some.org/nsURI" name=“name1” value=“newValue " />’ }); print ‘Name:’ . $object->get_name . ‘ Value:’ . $object->get_value;
9. SQL Mapping Supported by querySQL call, it goes recursively through the objects tree and returns ref to hash with contents of the mapped XML elements. For the previously defined parameter element: Example: XML serilaized into $object: <nsid1:myParameter name='name1' value='100/> <nsid1:myParameter name='name2' value='200/> call $object->querySQL($hash_ref_to_return); $hash_ref_to_return is { tableName => { field1 => '100' , field2 => '200'} } where it can be easily passed to any of SQL ORM frameworks. For example: in case of Class::DBI: my @records = TableName->search(%{ $hash_ref_to_return} ); or with minor refactoring in Rose::DB::Object my @records = TableName::Manager->get_tablenames( query => [ field1 => { eq => $hash_ref_to_return->{field1} }, field2 => { eq => $hash_ref_to_return->{field2} }, ] );
10. The rest of the story Centralized logging is supported by Log::Log4perl module Each module is throughly documented with pod Test suit is built for each generated class There are perlcritic and perltidy profiles created for the API and perlcritic parsing is an integral part of the module testing Essentially, one can create a bunch of RelaxNG or XML schema derived CPAN modules in a matter of minutes and pollute XML:: namespace even more Or one can start schema derived API with properly formed classes and follow the same style and utilize automated tests to assure enterprise level quality of the software (and perl needs it badly)
11.
12. Questions ? Oh, and yes, perl is indeed unDead ! Links: Links: PXB project on Google code – http://code.google.com/p/pxb/w/list perfSONAR-PS wiki - https://wiki.internet2.edu/confluence/display/PSPS