The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

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.51, built on August 10, 2007. Website: http://perl.overmeer.net/xml-compile/

LICENSE

Copyrights 2006-2007 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