Provided by: libxml-compile-perl_1.63-2_all bug

NAME

       XML::Compile::FAQ - frequently asked questions

DESCRIPTION

       On this page, a wild collection of questions are answered.  If you have contributions
       either in question or as answer, then please contribute via the mailinglist.

       See also XML::Compile::SOAP::FAQ.

   The data structure
       what do the cho_, seq_ and all_ start of labels mean?

       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 "cho_tic" is used to represent the following nameless choice block:

         <choice>
           <element name="tic" />
           <element name="tac" />
           <element name="toe" />
         </choice>

       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 "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 "prefixes" option or by
       default from the XML schemas.

       See "Key rewrite" in XML::Compile::Schema for the full list of options.

       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.

       Producting 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);

   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.

       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 "targetNamespace" is "namespace-less".  The *FormDefault defaults are
       "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 "new()" directly.

         my $schema = XML::Compile::Schema->new("schema.xsd"
            , target_namespace     => 'http://my-namespace'
            , element_form_default => 'qualified'
            );

       If you use the XML::Compile::Cache object, which extends ::Schema, then you have a nice
       "printIndex" method which shows you what has been read.

       schema location

       The official idea about the use of schema's, is that you get the latest version of them on
       the moment you start the application.  There are two major problems with that:

       . you may not have (a working) internet connection on that moment
       . remote changes in the spec may break your application unexpectedly

       In general, IMO as author of the XML::Compile suite, you should never want this dynamic,
       unpredictable behavior!

       Besides, the content of the "schemaLocation" attribute to "import", "include" and "schema"
       elements are usually broken, missing and/or flawed.  You can better do it by hand.

       Collect the schema's you need in a directory.  The name of the schema file does not need
       to means anything useful.  Then, add the location where the schema's are found:

          my $schema = XML::Compile::Cache->new;
          $schema->addSchemaDirs($my_schema_dir);

       Add the mapping from namespaces to filenames (you may provide an ARRAY of names or use the
       same namespace multiple times).  It is useful to have a constant defined for your
       namespace.

          use constant MY_NS => 'http://very-long';
          $schema->knownNamespace(&MY_NS => 'schemafile.xsd');
          $schema->importDefinitions(MY_NS, @options);

       There is also a less clean solution:

          my $schema = XML::Compile::Cache->new('schemafile.xsd', @options);

       When you have many xsd's to include, you may do this:

          my @xsds = glob "$my_schema_dir/*.xsd";
          my $schema = XML::Compile::Cache->new;
          $schema->knownNamespace(&MY_NS => \@xsds);
          $schema->importDefinitions(MY_NS, @options);

       or

          my $schema = XML::Compile::Cache->new(\@xsds, @options);

       fixing schemas

       Many schema's are broken.  XML::Compile is not a good tool to figure-out what is wrong
       with the schema.  Have you tried "xmllint"?  Sometimes, you get sufficient help adding to
       the top of your script:

          use Log::Report mode => 'DEBUG';

       When you know what is wrong, you can overrule parts of the schema by redefining elements;
       simply: the last definition for an element wins.  For instance:

          $schema->importDefinition(<<'_PATCH');
          <schema ....>
            <element name="has_bug">
               ...
            </element>
          _PATCH

       Of course, you can also use an external file for this.

       Example

       This is a piece of code actually used.  It shows various complications when an external
       schema is "loaded" "dynamically" into another schema.

         # In the top of your script
         my $schema_dir = '/usr/share/schemas';
         my $xyz_ns     = 'http://www.xyzeorder.com/workflow';
         my $xyz_xsd    = 'xyzSchema.xsd';

         # In the main part of your script
         my $schema     = XML::Compile::Cache->new(....);
         $schema->addSchemaDirs($schema_dir);
         $schema->importDefinitions($xyz_xsd, target_namespace => $xyz_ns);
         $schema->addPrefixes(xyz => $xyz_ns);
         $schema->addKeyRewrite('PREFIXED(xyz)');

       The schema "forgets" to mention its "targetNamespace", so it is overruled.  The ::Cache
       extension handles prefixes much nicer than the ::Schema base object.  So, with
       reading/writing the hash keys which relate to the elements in this schema will have "xyz_"
       as prefix for clarity.

   Processing
       my data is not recognized

       You do specify the data in your structure, but it seems not to be recognized.  See "wrong
       error message"

       wrong error message

       You may get an error message about a "missing data item" on a higher structural level than
       where the problem actually is.  This especially happens with unions and
       substitutionGroups.  The problem is cause by the fact that on a certain structural level,
       multiple alternatives may appear which only differ many levels deep in structure.  X::C
       needs to scan all the alternatives, and when all fail it does not know which of the
       alternatives was "the best" alternative.

       Try turning on debugging with:

         use Log::Report  mode => "DEBUG";

SEE ALSO

       This module is part of XML-Compile distribution version 1.63, built on July 02, 2019.
       Website: http://perl.overmeer.net/xml-compile/

LICENSE

       Copyrights 2006-2019 by [Mark Overmeer <markov@cpan.org>]. 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://dev.perl.org/licenses/