.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "XML::Compile::Translate::Writer 3pm" .TH XML::Compile::Translate::Writer 3pm "2022-11-27" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" XML::Compile::Translate::Writer \- translate HASH to XML .SH "INHERITANCE" .IX Header "INHERITANCE" .Vb 2 \& XML::Compile::Translate::Writer \& is a XML::Compile::Translate .Ve .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 2 \& my $schema = XML::Compile::Schema\->new(...); \& my $code = $schema\->compile(WRITER => ...); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" The translator understands schemas, but does not encode that into actions. This module implements those actions to translate from a (nested) Perl \s-1HASH\s0 structure onto \s-1XML.\s0 .PP Extends \*(L"\s-1DESCRIPTION\*(R"\s0 in XML::Compile::Translate. .SH "METHODS" .IX Header "METHODS" Extends \*(L"\s-1METHODS\*(R"\s0 in XML::Compile::Translate. .SH "DETAILS" .IX Header "DETAILS" Extends \*(L"\s-1DETAILS\*(R"\s0 in XML::Compile::Translate. .SS "Translator options" .IX Subsection "Translator options" Extends \*(L"Translator options\*(R" in XML::Compile::Translate. .SS "Processing Wildcards" .IX Subsection "Processing Wildcards" Complex elements can define \f(CW\*(C`any\*(C'\fR (element) and \f(CW\*(C`anyAttribute\*(C'\fR 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. .PP The procedure for the \s-1WRITER\s0 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 \f(CW\*(C`{namespace}type\*(C'\fR. The \fInamespace\fR component is important, because only spec conformant namespaces will be used. The elements and attributes are added in random order. .SS "Mixed elements" .IX Subsection "Mixed elements" [0.79] ComplexType and ComplexContent components can be declared with the \&\f(CW\*(C` attribute. .PP XML::Compile does not have a way to express these mixtures of information and text as Perl data-structures; the only way you can use those to the full extend, is by juggling with XML::LibXML nodes yourself. .PP You may provide a XML::LibXML::Element, which is complete, or a \&\s-1HASH\s0 which contains attributes values and an \s-1XML\s0 node with key '_'. When '_' contains a string, it will be translated into an \s-1XML\s0 text node. .PP XML::Compile::Schema::compile(mixed_elements) can be set to .IP "\s-1ATTRIBUTES\s0 (default)" 4 .IX Item "ATTRIBUTES (default)" Add attributes to the provided node. When you provide a \s-1HASH,\s0 it is taken as node content with attributes. The content has to be stored with key '_'. When it is not a \s-1HASH,\s0 the data is node content. .Sp There are various ways you can specify content. Up to [1.51], you could only pass a matching XML::LibXML::Element. Release [1.51] added strings to the spectrum. If the string does not contain encoded entities or < and >, then it is assumed to be a real perl string. When the string contains an \s-1XML\s0 fragment which has the same localname as to be created, that will be used. When the \s-1XML\s0 fragment is not wrapped in the expected node, this is created for you. .Sp In any case, attributes provided with the content will get added to the content data. .IP "\s-1STRUCTURAL\s0" 4 .IX Item "STRUCTURAL" [0.89] behaves as if the attribute is not there: a data-structure can be used or an \s-1XML\s0 node. .SS "Schema hooks" .IX Subsection "Schema hooks" All writer hooks behave differently. Be warned that the user values can be a \s-1SCALAR\s0 or a \s-1HASH,\s0 dependent on the type. You can intervene on higher data-structure levels, to repair lower levels, if you want to. .PP [1.48] The hooks get a long list of parameters. The \f(CW$fulltype\fR indicates the type of object which is being processed, which is especially useful with the 'extends' selector. .PP \fIhooks executed before normal processing\fR .IX Subsection "hooks executed before normal processing" .PP The \f(CW\*(C`before\*(C'\fR hook gives you the opportunity to fix the user supplied data structure. The \s-1XML\s0 generator will complain about missing, superfluous, and erroneous values which you probably want to avoid. .PP The \f(CW\*(C`before\*(C'\fR hook returns new values. Just must not interfere with the user provided data. When \f(CW\*(C`undef\*(C'\fR is returned, the whole node will be cancelled. .PP On the moment, the only predefined \f(CW\*(C`before\*(C'\fR hook is \f(CW\*(C`PRINT_PATH\*(C'\fR. .PP \fIhooks replacing the usual \s-1XML\s0 node generation\fR .IX Subsection "hooks replacing the usual XML node generation" .PP Only one \f(CW\*(C`replace\*(C'\fR hook can be defined. It must return a XML::LibXML::Node or \f(CW\*(C`undef\*(C'\fR. The hook must use the \&\f(CW\*(C`XML::LibXML::Document\*(C'\fR node (which is provided as first argument) to create a node. .PP As parameters, the called replace function will receive the document, user-provided values, location in the data tree (for error messages), the tag of the node with prefix attached, and a reference to the code which would be executed if the replace hook had not been active. .PP On the moment, the only predefined \f(CW\*(C`replace\*(C'\fR hook is \f(CW\*(C`SKIP\*(C'\fR. .PP \fIhooks executed after the node was created\fR .IX Subsection "hooks executed after the node was created" .PP The \f(CW\*(C`after\*(C'\fR hooks, will each get a chance to modify the produced \s-1XML\s0 node, for instance to encapsulate it. Each time, the new \s-1XML\s0 node has to be returned. .PP On the moment, the only predefined \f(CW\*(C`after\*(C'\fR hook is \f(CW\*(C`PRINT_PATH\*(C'\fR. .PP \fIfixing bad schemas\fR .IX Subsection "fixing bad schemas" .PP 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). .SS "Typemaps" .IX Subsection "Typemaps" In a typemap, a relation between an \s-1XML\s0 element type and a Perl class (or object) is made. Each translator back-end will implement this a little differently. This section is about how the writer handles typemaps. .PP \fITypemap to Class\fR .IX Subsection "Typemap to Class" .PP Usually, an \s-1XML\s0 type will be mapped on a Perl class. The Perl class implements the \f(CW\*(C`toXML\*(C'\fR method as serializer. That method should either return a data structure which fits that of the specific type, or an XML::LibXML::Element. .PP When translating the data-structure to \s-1XML,\s0 the process may encounter objects. Only if these objects appear at locations where a typemap is defined, they are treated smartly. When some other data than an objects is found on a location which has a typemap definition, it will be used as such; objects are optional. .PP The object (if present) will be checked to be of the expected class. It will be a compile-time error when the class does not implement the \&\f(CW\*(C`toXML\*(C'\fR method. .PP .Vb 1 \& $schema\->typemap($sometype => \*(AqMy::Perl::Class\*(Aq); \& \& package My::Perl::Class; \& ... \& sub toXML \& { my ($self, $xmltype, $doc) = @_; \& ... \& { a => { b => 42 }, c => \*(Aqaaa\*(Aq }; \& } .Ve .PP The \f(CW$self\fR is the object found in the data-structure provided by the user. \f(CW$doc\fR can be used to create your own XML::LibXML::Element. It is possible to use the same object on locations for different types: in this case, the toXML method can distiguisk what kind of data to return based on the \f(CW$xmltype\fR. .PP \fITypemap to Object\fR .IX Subsection "Typemap to Object" .PP In this case, some helper object arranges the serialization of the provided object. This is especially useful when the provided object does not have the toXML implemented, for instance because it is an implementation not under your control. The helper object works like an interface. .PP .Vb 2 \& my $object = My::Perl::Class\->new(...); \& $schema\->typemap($sometype => $object); \& \& package My::Perl::Class; \& sub toXML \& { my ($self, $object, $xmltype, $doc) = @_; \& ... \& } .Ve .PP The toXML will only be called then \f(CW$object\fR is blessed. If you wish to have access to some data-type in any case, then use a simple \*(L"before\*(R" hook. .PP \fITypemap to \s-1CODE\s0\fR .IX Subsection "Typemap to CODE" .PP The light version of an interface object uses \s-1CODE\s0 references. The \s-1CODE\s0 reference is only called if a blessed value is found in the user provided data. It cannot be checked automatically whether it is blessed according to the expectation. .PP .Vb 1 \& $schema\->typemap($t1 => \e&myhandler); \& \& sub myhandler \& { my ($backend, $object, $xmltype, $doc) = @_; \& ... \& } .Ve .PP \fITypemap implementation\fR .IX Subsection "Typemap implementation" .PP The typemap for the writer is implemented as a 'before' hook: just before the writer wants to start. .PP Of course, it could have been implemented by accepting an object anywhere in the input data. However, this would mean that all the (many) internal parser constructs would need to be extended. That would slow-down the writer considerably. .SH "SEE ALSO" .IX Header "SEE ALSO" This module is part of XML-Compile distribution version 1.63, built on July 02, 2019. Website: \fIhttp://perl.overmeer.net/xml\-compile/\fR .SH "LICENSE" .IX Header "LICENSE" Copyrights 2006\-2019 by [Mark Overmeer ]. For other contributors see ChangeLog. .PP This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See \fIhttp://dev.perl.org/licenses/\fR