NAME
XML::Compile::Schema::XmlWriter - bricks to translate HASH to XML
INHERITANCE
SYNOPSIS
my $schema = XML::Compile::Schema->new(...);
my $code = $schema->compile(WRITER => ...);
DESCRIPTION
The translator understands schemas, but does not encode that into actions. This module implements those actions to translate from a (nested) Perl HASH structure onto XML.
DETAILS
Processing Wildcards
Complex elements can define any
(element) and anyAttribute
components, with unpredictable content. In this case, you are quite on your own in processing those constructs. The use of both schema components should be avoided: please specify your data-structures explicit by clean type extensions.
The procedure for the XmlWriter is simple: add key-value pairs to your hash, in which the value is a fully prepared XML::LibXML::Attr or XML::LibXML::Element. The keys have the form {namespace}type
. The namespace component is important, because only spec conformant namespaces will be used. The elements and attributes are added in random order.
example: specify anyAttribute
use XML::Compile::Util qw/pack_type/;
my $attr = $doc->createAttributeNS($somens, $sometype, 42);
my $h = { a => 12 # normal element or attribute
, "{$somens}$sometype" => $attr # anyAttribute
, pack_type($somens, $mytype) => $attr # nicer
};
Schema hooks
All writer hooks behave differently. Be warned that the user values can be a SCALAR or a HASH, dependent on the type. You can intervene on higher data-structure levels, to repair lower levels, if you want to.
hooks executed before normal processing
The before
hook gives you the opportunity to fix the user supplied data structure. The XML generator will complain about missing, superfluous, and erroneous values which you probably want to avoid.
The before
hook returns new values. Just must not interfere with the user provided data. When undef
is returned, the whole node will be cancelled.
On the moment, the only predefined before
hook is PRINT_PATH
.
example: before hook on user-provided HASH.
sub before_on_complex($$$)
{ my ($doc, $values, $path) = @_;
my %copy = %$values;
$copy{extra} = 42;
delete $copy{superfluous};
$copy{count} =~ s/\D//g; # only digits
\%copy;
}
example: before hook on simpleType data
sub before_on_simple($$$)
{ my ($doc, $value, $path) = @_;
$value *= 100; # convert euro to euro-cents
}
example: before hook with object for complexType
sub before_on_object($$$)
{ my ($doc, $obj, $path) = @_;
+{ name => $obj->name
, price => $obj->euro
, currency => 'EUR'
};
}
hooks replacing the usual XML node generation
Only one replace
hook can be defined. It must return a XML::LibXML::Node or undef
. The hook must use the XML::LibXML::Document
node (which is provided as first argument) to create a node.
On the moment, the only predefined replace
hook is SKIP
.
example: replace hook
sub replace($$$)
{ my ($doc, $values, $path, $tag) = @_
my $node = $doc->createElement($tag);
$node->appendText($values->{text});
$node;
}
hooks executed after the node was created
The after
hooks, will each get a chance to modify the produced XML node, for instance to encapsulate it. Each time, the new XML node has to be returned.
On the moment, the only predefined after
hook is PRINT_PATH
.
example: add an extra sibbling after the usual process
sub after($$$$)
{ my ($doc, $node, $path) = @_;
my $child = $doc->createAttributeNS($myns, earth => 42);
$node->addChild($child);
$node;
}
fixing bad schemas
When a schema makes a mess out of things, we can fix that with hooks. Also, when you need things that XML::Compile does not support (yet).
example: creating nodes with text
{ my $text;
sub before($$$)
{ my ($doc, $values, $path) = @_;
my %copy = %$values;
$text = delete $copy{text};
\%copy;
}
sub after($$$)
{ my ($doc, $node, $path) = @_;
$node->addChild($doc->createTextNode($text));
$node;
}
$schema->addHook
( type => 'mixed'
, before => \&before
, after => \&after
);
}
SEE ALSO
This module is part of XML-Compile distribution version 0.64, built on January 07, 2008. Website: http://perl.overmeer.net/xml-compile/
LICENSE
Copyrights 2006-2008 by Mark Overmeer. For other contributors see ChangeLog.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html