NAME Validation::Class::Document - Data Validation for Hierarchical Data VERSION version 0.000016 SYNOPSIS package MyApp::Person; use Validation::Class::Document; my $person = MyApp::Person->new; # rules my $schema = { 'id' => {mixin => [':num'], max_length => 4}, 'name' => {mixin => [':str'], min_length => 2}, 'title' => {mixin => [':str'], min_length => 5}, 'company.name' => {mixin => [':str'], min_length => 2}, 'company.tags.@' => {mixin => [':str'], min_length => 2}, 'company.super*.name' => {mixin => [':str'], min_length => 2}, 'company.super*.rating.@.*' => {mixin => [':str'], }, }; # data my $data = { "id" => "1234-ABC", "name" => "Anita Campbell-Green", "title" => "Designer", "company" => { "name" => "House of de Vil", "supervisor" => { "name" => "Cruella de Vil", "rating" => [ { "support" => -9, "guidance" => -9 } ] }, "tags" => [ "evil", "cruelty", "dogs" ] }, }; unless ($person->validate_document($schema => $data)) { warn $person->errors_to_string if $person->error_count; } DESCRIPTION Validation::Class::Document inherits all functionality from Validation::Class and implements additional abilities documented as follows. This module allows you to validate hierarchical structures using the Validation::Class framework. This is an experimental yet highly promising approach toward the consistent processing of nested structures. The current interface is not expected to change. This module was inspired by MooseX::Validation::Doctypes. Gone are the days of data submitted to an application in key/value form and especially in regards to the increasing demand for communication between applications, serializing and transmitting structured data over a network connection. Note! All matching data points will be validated forcefully (i.e. matching data points are required to have a value defined). OVERVIEW Validation::Class::Document exports the document (or dom) keyword which allows you to pre-define/configure your path matching rules for your data structure. The "path matching rules", which is actually a custom object notation, referred to as the document notation, can be thought of as a kind-of simplified regular expression which is executed against the flattened data structure. The following are a few general use-cases: # given this JSON data structure { "id": "1234-A", "name": { "first_name" : "Bob", "last_name" : "Smith", }, "title": "CIO", "friends" : [], } # select id to validate against the string rules document 'foobar' => { 'id' => 'string' }; # select name -> first_name/last_name to validate against the string rules document 'foobar' => {'name.first_name' => 'string', 'name.last_name' => 'string'}; # or document 'foobar' => {'name.*_name' => 'string'}; # select each element in friends to validate against the string rules document 'foobar' => { 'friends.@' => 'string' }; # or select an element of a hashref in each element in friends to validate document 'foobar' => { 'friends.@.name' => 'string' }; The document declaration's keys should follow the aforementioned document notation schema and it's values should be strings which correspond to the names of fields (or other document declarations) that will be used to preform the data validation. It is possible to combine document declarations to validate hierarchical data that contains data structures matching one or more document patterns. The following is an example of what that might look like. package MyApp::Person; use Validation::Class::Document; # data validation rule field 'name' => { mixin => [':str'], pattern => qr/^[A-Za-z ]+$/, max_length => 20, }; # data validation map / document notation schema document 'friend' => { 'name' => 'name' }; # data validation map / document notation schema document 'person' => { 'name' => 'name', 'friends.@' => 'friend' }; package main; my $data = { "name" => "Anita Campbell-Green", "friends" => [ { "name" => "Horace" }, { "name" => "Skinner" }, { "name" => "Alonzo" }, { "name" => "Frederick" }, ], }; my $person = MyApp::Person->new; unless ($person->validate_document(person => $data)) { warn $person->errors_to_string if $person->error_count; } Alternatively, the following is a more verbose data validation class using traditional styling and configuration. package MyApp::Person; use Validation::Class::Document; field 'id' => { mixin => [':str'], filters => ['numeric'], max_length => 2, }; field 'name' => { mixin => [':str'], pattern => qr/^[A-Za-z ]+$/, max_length => 20, }; field 'rating' => { mixin => [':str'], pattern => qr/^\-?\d+$/, }; field 'tag' => { mixin => [':str'], pattern => qr/^(?!evil)\w+/, max_length => 20, }; document 'person' => { 'id' => 'id', 'name' => 'name', 'company.name' => 'name', 'company.supervisor.name' => 'name', 'company.supervisor.rating.@.*' => 'rating', 'company.tags.@' => 'name' }; package main; my $data = { "id" => "1234-ABC", "name" => "Anita Campbell-Green", "title" => "Designer", "company" => { "name" => "House of de Vil", "supervisor" => { "name" => "Cruella de Vil", "rating" => [ { "support" => -9, "guidance" => -9 } ] }, "tags" => [ "evil", "cruelty", "dogs" ] }, }; my $person = MyApp::Person->new; unless ($person->validate_document(person => $data)) { warn $person->errors_to_string if $person->error_count; } METHODS validate_document The validate_document method (or document_validates) is used to validate the specified hierarchical data against the specified document declaration. This is extremely valuable for validating serialized messages passed between machines. This method requires two arguments, the name of the document declaration to be used, and the data to be validated which should be submitted in the form of a hashref. The following is an example of this technique: my $boolean = $self->validate_document(foobar => $data); Additionally, you may submit options in the form of a hashref to further control the validation process. The following is an example of this technique: # the prune option removes non-matching parameters (nodes) my $boolean = $self->validate_document(foobar => $data, { prune => 1 }); Additionally, to support the validation of ad-hoc specifications, you may pass this method two hashrefs, the first being the document notation schema, and the second being the hierarchical data you wish to validate. AUTHOR Al Newkirk COPYRIGHT AND LICENSE This software is copyright (c) 2013 by Al Newkirk. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.