blob: 2e21fde9a820fe456709489b3a34e9a36d6e07aa [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Distribution License v. 1.0, which is available at
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: BSD-3-Clause
-->
<!DOCTYPE book [
<!ENTITY % ents SYSTEM "docbook.ent">
%ents;
]>
<section version="5.0" xml:id="compiling-xml-schema-dealing-with-errors"
xml:lang="en" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ns5="http://www.w3.org/1999/xhtml"
xmlns:ns3="http://www.w3.org/2000/svg"
xmlns:ns="http://docbook.org/ns/docbook"
xmlns:m="http://www.w3.org/1998/Math/MathML">
<title>Dealing with errors</title>
<section xml:id="Schema_errors">
<title>Schema errors</title>
<para>Because XML Schema is so complicated, and because there are a
lot of tools out there do not implement the spec correctly, it is
often the case that a schema you are trying to compile has some real
errors in it. When this is the case, you'll see XJC reporting somewhat
cryptic errors such as <literal>rcase-RecurseLax.2: There is not a
complete functional mapping between the particles.</literal></para>
<para>The &binding.impl.name; uses the schema correctness checker from the
underlying JAXP implementation, which is the JAXP RI in a typical
setup. The JAXP RI is one of the most conformant schema validators,
and therefore most likely correct. So the first course of action
usually is to fix problems in the schema.</para>
<para>However, in some situations, you might not have an authority to
make changes to the schema. If that is the case and you really need to
compile the schema, you can bypass the correctness check by using the
<option>-nv</option> option in XJC. When you do this, keep in mind
that you are possibly feeding "garbage" in, so you may see XJC choke
with some random exception.</para>
</section>
<section xml:id="Property__fooBarZot__is_already_defined">
<title>Property 'fooBarZot' is already defined</title>
<para>One of the typical errors you'll see when compiling a complex
schema is:</para>
<example>
<title>Multiple property definitions error</title>
<programlisting language="output"><![CDATA[parsing a schema...
[ERROR] Property "MiOrMoOrMn" is already defined.
line 132 of
file:/C:/kohsuke/Sun/JAXB/jaxb-unit/schemas/individual/MathML2/presentation/scripts.xsd
[ERROR] The following location is relevant to the above error
line 138 of
file:/C:/kohsuke/Sun/JAXB/jaxb-unit/schemas/individual/MathML2/presentation/scripts.xsd]]></programlisting>
</example>
<para>This is an actual example of the offending part of a schema,
taken from MathML. If you go to line 132 of
<filename>scripts.xsd</filename>, you'll see that it has a somewhat
complicated content model definition:</para>
<example>
<title>Multiple property definitions in MathML</title>
<programlisting language="xml"><![CDATA[<xs:group name="mmultiscripts.content">
<xs:sequence>
<xs:group ref="Presentation-expr.class"/>
<xs:sequence minOccurs="0" maxOccurs="unbounded"> <!-- line 132 -->
<xs:group ref="Presentation-expr-or-none.class"/>
<xs:group ref="Presentation-expr-or-none.class"/>
</xs:sequence>
<xs:sequence minOccurs="0">
<xs:element ref="mprescripts"/>
<xs:sequence maxOccurs="unbounded"> <!-- line 138 -->
<xs:group ref="Presentation-expr-or-none.class"/>
<xs:group ref="Presentation-expr-or-none.class"/>
</xs:sequence>
</xs:sequence>
</xs:sequence>
</xs:group>]]></programlisting>
</example>
<para>This is a standard technique in designing a schema. When you
want to say "in this element, <literal>B</literal> can occur arbitrary
times, but <literal>C</literal> can occur only up to once", you write
this as <literal>B*,(C,B*)?</literal>. This, however, confuses &binding.impl.name;,
because it tries to bind the first <literal>B</literal> to its own
property, then <literal>C</literal> to its own property, then the
second <literal>B</literal> to its own property, and so we end up
having a collision again.</para>
<para>In this particular case, <literal>B</literal> isn't a single
element but it's a choice of large number of elements abstracted away
in <literal>&lt;xs:group&gt;</literal>s, so they are hard to see. But
if you see the same content model referring to the same element/group
twice in a different place, you can suspect this.</para>
<para>In this case, you'd probably want the whole thing to map to a
single list so that you can retain the order those elements show up in
the document. You can do this by putting the same
<literal>&lt;jaxb:property&gt;</literal> customization on the whole
"<literal>mmultiscripts.content</literal>" model group, like this (or
you can do it externally with XPath):</para>
<example>
<title>How to fix the problem?</title>
<programlisting language="xml"><![CDATA[<xs:groupname="mmultiscripts.content">
<xs:annotation>
<xs:appinfo>
<jaxb:propertyname="content"/>
</xs:appinfo>
</xs:annotation>
<xs:sequence>
<xs:groupref="Presentation-expr.class"/>]]></programlisting>
</example>
<para>Another way to fix this problem is to use the
simpler and better binding mode in XJC, which is a &binding.impl.name;
vendor extension.</para>
</section>
<section xml:id="Two_declarations_cause_a_collision_in_the_ObjectFactory_class">
<title>Two declarations cause a collision in the ObjectFactory
class</title>
<para>When schemas contain similar looking element/type names, they
can result in "Two declarations cause a collision in the ObjectFactory
class" errors. To be more precise, for each of all types and many
elements (exactly what elements get a factory and what doesn't is bit
tricky to explain), XJC produces one method on the
<literal>ObjectFactory</literal> class in the same package. The
<literal>ObjectFactory</literal> class is created for each package that XJC
generates some files into. The name of the method is derived from XML
element/type names, and the error is reported if two elements/types
try to generate the same method name.</para>
<para>There are two approaches to fix this problem. If the collision
is coming from two different schemas with different target namespaces,
then you can easily avoid the collision by compiling them into
different Java packages. To do this, use <literal>&lt;schemabindings&gt;</literal>
customization on two schemas and specify the package name.</para>
<para>Another way to fix this problem is to use <literal>&lt;factoryMethod&gt;</literal>
customization on two conflicting elements/types to specify different
factory method names. This can be used in all cases, but if you have a
large number of conflicts, you'll have to specify this customization
one by one.</para>
<para>Notice that <literal>&lt;class&gt;</literal>
customization doesn't affect the <literal>ObjectFactory</literal> method
name by itself.</para>
</section>
<section xml:id="Customization_errors">
<title>Customization errors</title>
<section xml:id="XPath_evaluation_of_____results_in_empty_target_node">
<title>XPath evaluation of ... results in empty target
node</title>
<para>External &binding.spec.name; customizations are specified by using XPath
(or using <link
linkend="customization-of-schema-compilation-using-scd-for-customizations">SCD</link>.)
This works by writing an XPath expression that matches a
particular element in the schema document. For example, given the
following schema and binding file:</para>
<example>
<title>Schema and external binding file</title>
<formalpara>
<title><filename>test.xsd</filename></title>
<para><programlisting language="xml"><![CDATA[<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexTypename="foo"/>
</xs:schema>]]></programlisting></para>
</formalpara>
<formalpara>
<title><filename>test.xjb</filename></title>
<para><programlisting language="xml"><![CDATA[<bindings version="3.0" xmlns="https://jakarta.ee/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<bindings schemaLocation="test.xsd">
<bindings node="//xs:complexType[@name='foo']">
<classname="Bar"/>
</bindings>
</bindings>
</bindings>]]></programlisting></para>
</formalpara>
</example>
<para>will be interpreted as if the class customization is
attached to the complex type '<literal>foo</literal>'.</para>
<para>For this to work, the XPath expression needs to match one
and only one element in the schema document. When the XPath
expression is incorrect and it didn't match anything, you get this
"XPath evaluation of ... results in empty target node"
problem.</para>
<para>Common causes of this problem include typos, incorrect
namespace URI declarations, and misunderstanding of XPath.</para>
</section>
</section>
</section>