XML-Compile
view release on metacpan or search on metacpan
lib/XML/Compile/FAQ.pod view on Meta::CPAN
X::C tries to give you a simple data-structure in Perl, however XML
does not always map directly only that. One such situation is where
you have blocks within a list of elements. In such case, the block gets
a name which is composed by the type of block and the first element in
the block. You will encounter these names in some error messages and
when these block have a maxOccurs larger than 1.
Example. The name C<cho_tic> is used to represent the following nameless
choice block:
<choice>
<element name="tic" />
<element name="tac" />
<element name="toe" />
</choice>
=head3 localName collission
In the default behavior, only the "local" names of the XML elements are
used in the Perl structure. However, it is very well possible that the
same name appears in more than on XML name-space, used within the same
data structure. So see this often with substitutionGroups.
When collissions happen, you have to switch to use
C<< key_rewrite => 'PREFIXED' >> in the compile rules. All keys will
now get rewritten: the name-space prefix will be prepended. The prefixes
are defined by the mapping table provided with the C<< prefixes >> option
or by default from the XML schemas.
See L<XML::Compile::Schema/"Key rewrite"> for the full list of options.
=head3 Overruling produced structures (writer)
You may encounter broken servers. Actually, I have seen even expensive
server implementations and professional high-profile services which do
not follow the rules...
On any location in the data structure you provide, you can give a value
but also a fully prepared XML::LibXML node. For instance
my $doc = XML::LibXML::Document->new('1.1', 'UTF-8');
my $node = $doc->createElement('field);
$node->appendText(42);
my $xml = $schema->writer($type)->($doc, { field => $node });
$doc->setDocumentElement($xml);
print $xml->toString(1); # perl string
print $doc->toString(1); # bytes
You will probably need more than one attempt to produce the correct
output... Only use this when you are sure that the receiving party
is broken.
=head3 Producing CDATA blocks (writer)
To get CDATA blocks, the solution is very close to the example in the
previous section:
my $doc = XML::LibXML::Document->new('1.1', 'UTF-8');
my $cdata = $doc->createCDATASection($content);
my $xml = $schema->writer($type)->($doc, { field => $cdata });
$doc->setDocumentElement($xml);
The "$content" is a Perl string, which means that it needs to be
utf8 when it is utf8. For instance:
use File::Slurp::Tiny;
my $content = read_file $filename, binmode => 'utf8';
my $cdata = $doc->createCDATASection($content);
When using SOAP (with or without WSDL) you need to do something like
this:
use XML::LibXML; # for ::Document
my $wsdl = ...usual...
my $doc = XML::LibXML::Document->new('1.0', 'UTF-8');
my %data = (
_doc => $doc,
password => $doc->createCDATASection($password),
);
$wsdl->call(Login => \%data);
The XML which is sent is usually created inside the client library, but
you need to create the CDATA block inside the same document structure.
But the C<_doc> provides a way to use your own document object. Do not
reuse it over multiple calls!
=head2 Schemas
Be aware that the "2001" schema specification is continuously under
development. So, the namespace has not been changed over time, but
the content has.
=head3 qualified elements
One of the more noticeable problems with schemas is the specification of
the namespaces to be used for the schema. In older schema's, like many
important protocols, there was no way to specify whether elements should
be used qualified or not. Some schema's lack the target namespace
declaration. Those fields did not exist in earlier versions of the
"2001" spec; it was defined in the documentation.
So, what you may encounter is something like:
<schema xmlns="http://www.w3.org/2001/XMLSchema">
where (in the current syntax) it should have been
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://my-namespace"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
The default for C<targetNamespace> is "namespace-less". The C<*FormDefault>
defaults are C<unqualified>, which is a pity: most schemas will use
qualified elements.
Of course, you can add these fields to the schema file, but that violates
the intergrity of that external resource. Therefore, use options:
my $schema = XML::Compile::Schema->new;
$schema->importDefinitions("schema.xsd"
, target_namespace => 'http://my-namespace'
, element_form_default => 'qualified'
);
You may also provide all these options with C<new()> directly.
( run in 0.653 second using v1.01-cache-2.11-cpan-39bf76dae61 )