![Page 1: 2008-08-13 MARKOV Solutions Mark Overmeer MARKOV@cpan.org YAPC::EU 2008 From XML (schema) to Application](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/1.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/2.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/3.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/4.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/5.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/6.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/7.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/8.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/9.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/10.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/11.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/12.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/13.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/14.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/15.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/16.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/17.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/18.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/19.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/20.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/21.jpg)
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](https://reader030.vdocuments.us/reader030/viewer/2022032709/56649ec55503460f94bd0ec4/html5/thumbnails/22.jpg)
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;}