2008-08-13 markov solutions mark overmeer [email protected] yapc::eu 2008 from xml (schema) to...

22
2008-08- 13 MARKOV Solutions http://perl.overmeer.net Mark Overmeer [email protected] YAPC::EU 2008 From XML (schema) to Application

Upload: kathleen-chambers

Post on 01-Jan-2016

222 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

2008-08-13

MARKOV Solutionshttp://perl.overmeer.net

Mark [email protected]

YAPC::EU 2008

From XML (schema) to Application

Page 2: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

2008-08-13

MARKOV Solutionshttp://perl.overmeer.net

Mark [email protected]

YAPC::EU 2008

From XML (schema) to Application

I HATE XML

Page 3: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

3

Objective

XML schema's are very popular

Schema/XML complicationsname-spacesstrongly typedverbose notationoften generated

Application complicationsmessage validation: strictnessschema locationschema versioning

XML::Compile suite helps!

Page 4: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

4

XML::Compile

Advantages over other XML modules:very strict following the rules: no DWIM, no guessingusually no need for name-space understanding"slow" compile phase, then fast runvery close to 100% support: no known bugs

Page 5: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

5

XML::Compile

Advantages over other XML modules:very strict following the rules: no DWIM, no guessingusually no need for name-space understanding"slow" compile phase, then fast runvery close to 100% support: no known bugs

my $schema = XML::Compile::Schema->new($xsdfile);

Page 6: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

6

XML::Compile

Advantages over other XML modules:very strict following the rules: no DWIM, no guessingusually no need for name-space understanding"slow" compile phase, then fast runvery close to 100% support: no known bugs

my $schema = XML::Compile::Schema->new($xsdfile);

my $read = $schema->compile(READER => '{myns}mytype');my $hash = $read->($xml);print Dumper $hash;

Page 7: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

7

XML::Compile

Advantages over other XML modules:very strict following the rules: no DWIM, no guessingusually no need for name-space understanding"slow" compile phase, then fast runvery close to 100% support: no known bugs

my $schema = XML::Compile::Schema->new($xsdfile);

my $read = $schema->compile(READER => '{myns}mytype');my $hash = $read->($xml);print Dumper $hash;

my $doc = XML::LibXML::Document->new('1.0', 'UTF-8');my $write = $schema->compile(WRITER => '{myns}mytype');my $xml = $write->($doc, $hash);print $xml->toString(1);

Page 8: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

8

XML::Compile::Schema

Collects information from all used schema's

Organizes compilationX::C::Translate, with back-ends

X::C::T::Reader XML → HASHX::C::T::Writer HASH → XMLX::C::T::Template example generator

built-in typesname-space administration

Compilation results in code-refs

Page 9: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

9

XML::Compile::Cache

Extends X::C::Schemacompiled code-ref managementcompile option managementpre-compile for daemons orcompile-on-demand single shotuse of prefixes

Page 10: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

10

XML::Compile::Cache

Extends X::C::Schemacompiled code-ref managementcompile option managementpre-compile for daemons orcompile-on-demand single shotuse of prefixes

my @p = (myprefix => $mynamespace);my $schema = XML::Compile::Cache->new(prefixes => \@p);my $type = 'myprefix:mylocal'; # {mynamespace}mylocal

$schema->declare(READER => $type, @options);

# $schema->compileAll

my $data = $schema->reader($type)->($xml);my $xml = $schema->writer($type)->($doc, $data);

Page 11: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

11

Other modules for XML::Compile

XML::Compile::SOAP11XML::Compile::WSDL11

my $wsdl = XML::Compile::WSDL11->new($wsdlfile);my $call = $wsdl->compileClient('CallName');

my ($answer, $trace) = $call->($request);

Page 12: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

12

Other modules for XML::Compile

XML::Compile::SOAP11XML::Compile::WSDL11

XML::Compile::SOAP::Daemon

based on Net::Server and HTTP::Daemon

my $wsdl = XML::Compile::WSDL11->new($wsdlfile);my $call = $wsdl->compileClient('CallName');

my ($answer, $trace) = $call->($request);

my $daemon = XML::Compile::SOAP::HTTPDaemon->new;$daemon->operationsFromWSDL($wsdl, handlers => { CallName => \&handle_call } );$daemon->run;

Page 13: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

13

Other modules for XML::Compile

XML::Compile::TesterXML::Compile::DumperXML::Compile::Rewrite

XML::LibXML::Simple

xmlrewrite --plugin schema2001--xmlns xsd=$SCHEMA2001,me=$OTHER--no-annotations--no-comments--no-id-constraints--expand-includes--output reformated.xsd

To come:--no-elements version,bigone --extract-element--promote-unnamed 2 --no-unused-types--sort name ... etc ...

Page 14: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

14

Publish XML Interface

Module based on XML::Compile::Cache

Include all versions of the schema in the package

Collect validated message examplescreate readers for them, and study the resultwhich types are really used? (what to declare)

Create constants for name-spaces

Page 15: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

15

Example: Geo::KML

Geo::KML::Util

package Geo::KML::Util;use base 'Exporter';

my @kml21 = qw/NS_KML_21/;my @kml220 = qw/NS_KML_22 NS_ATOM_2005 NS_XAL_20/;

my @EXPORT = (@kml21, @kml220);my %EXPORT_TAGS = (kml21 => \@kml21, kml220 => \@kml22);

use constant NS_KML_21 => 'http://earth.google.com/kml/2.1';use constant NS_KML_22 => 'http://www.opengis.net/kml/2.2';use constant NS_ATOM_2005 => 'http://www.w3.org/2005/Atom';use constant NS_XAL_20 => 'urn:oasis:names:tc:ciq:xsdschema:xAL:2.0';

1;

Page 16: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

16

Example: Geo::KML

Protocol version

package Geo::KML;use base 'XML::Compile::Cache';

use Geo::KML::Util; # all constants

my %ns2version = ( &NS_KML_21 => '2.1' , &NS_KML_22 => '2.2.0');my %version2ns = reverse %ns2version;

# ::Cache::new { (bless {},$class)->init(\%args) }sub init($){ my ($self, $args) = @_; my $version = $args->{version} or die; $class->SUPER::init($args); ...

use Geo::KML;my $kml = Geo::KML->new(version => '2.2.0');

Page 17: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

17

Example: Geo::KML

Version specifics

my %info = ( '2.1' => { prefixes => [ '' => NS_KML_21 ] , schemas => [ 'kml-2.1/*.xsd' ] }

, '2.2.0' => { prefixes => [ '' => NS_KML_220, atom => NS_ATOM_2005 , xal => NS_XAL_20 ] , schemas => [ 'kml-2.2.0/*.xsd', 'atom-2005/*.xsd' , 'xal-2.0/*.xsd' ] } );

sub init($){ ... my $info = $info{$version} or die; $args->{prefixes} = $info->{prefixes}; $self->SUPER::init($args); ...

Page 18: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

18

Example: Geo::KML

Compile schema's

$info{'2.2.0'}{schemas} = ['kml-2.2.0/*.xsd', ...];

sub init($){ ... $self->SUPER::init($args); (my $xsd = __FILE__) =~ s!\.pm$!/xsd!;

my $patterns = $info{$version}{schemas}; my @xsds = map {glob "$xsd/$_"} @$patterns;

$self->importDefinitions(\@xsds);

lib/Geo/KML.pmlib/Geo/KML/Util.pmlib/Geo/KML/xsd/atom-2005/atom-author-link.xsdlib/Geo/KML/xsd/kml-2.2.0/ogckml22.xsdlib/Geo/KML/xsd/xal-2.0/xAL.xsd

Page 19: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

19

Example: Geo::KML

Read KML

sub init($){ ... $self->declare(READER => 'kml'); $self;}

sub readKML(@){ my ($class, $xml, %opts) = @_;

$xml->nodeName eq 'kml' or die; my $obj = $class->new(version => $xml->namespaceURI);

my $data = $obj->reader('kml')->($xml); return $data;

use Geo::KML;my ($type, $data) = Geo::KML->readKML('points.kmz');

name-space qualified!(empty prefix)

Page 20: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

20

Example: Geo::KML

Write KML

$self->declare(WRITER => 'kml', include_namespaces => 1);

sub writeKML($$){ my ($self, $data, $filename) = @_;

my $doc = XML::LibXML::Document->new('1.0', 'UTF-8');

my $xml = $self->writer('kml')->($doc, $data);

$doc->setDocumentElement($xml); $doc->toFile($filename, 1);}

Page 21: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

21

Example: Geo::KML

Write KML

use Geo::KML;

my %location = ( name => '' , description => '' , Point => {coordinates => [ "$long,$lat,0" ] } );

my %data = ( AbstractFeatureGroup => [ { Placemark => \%location }, ] );

my $kml = Geo::KML->new(version => '2.2.0');$kml->writeKML(\%data, 'example.kml');

Page 22: 2008-08-13 MARKOV Solutions  Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application

22

Example: Geo::KML

... and then ...simplify access to the data-structure

my %typemap = ( "{$kml22}Document" => Geo::KML::Document );$self->declare(RW => 'kml', typemap => \%typemap);

package Geo::KML::Document; # shows default implem.

sub toXML($$){ my ($self, $type, $doc) = @_; $self; # XML data-structure or XML node}

sub fromXML($$){ my ($class, $data, $type) = @_; bless $data, $class;}