Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
XML::Compile::FAQ(3)  User Contributed Perl Documentation XML::Compile::FAQ(3)

       XML::Compile::FAQ - frequently asked questions

       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:

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

       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);
	  my $xml  = $schema->writer($type)->($doc, { field => $node });

	  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

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

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

       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="">

       where (in the current syntax) it	should have been

	 <schema xmlns=""

       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

	 my $schema = XML::Compile::Schema->new;
	    , 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;

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


	  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 ....>
	    <element name="has_bug">

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


       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	= '';
	 my $xyz_xsd	= 'xyzSchema.xsd';

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

       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

       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";

       This module is part of XML-Compile distribution version 1.63, built on
       July 02,	2019. Website:

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

perl v5.32.1			  2019-07-02		  XML::Compile::FAQ(3)


Want to link to this manual page? Use this URL:

home | help