| <?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><xs:group></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><jaxb:property></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><schemabindings></literal> |
| customization on two schemas and specify the package name.</para> |
| |
| <para>Another way to fix this problem is to use <literal><factoryMethod></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><class></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> |