JAXB xjc generates fields as a list of elements - java

I have a problem with the following sequence of a wsdl file
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="allowCaseWithNewContract" type="xsd:boolean">
</xsd:element>
<xsd:choice minOccurs="0">
<xsd:element name="validationError" type="mnp:ErrorType"/>
<xsd:element name="internalError" type="mnp:ErrorType"/>
<xsd:element name="businessError" type="mnp:ErrorType"/>
<xsd:element name="externalError" type="mnp:ErrorType"/>
</xsd:choice>
</xsd:sequence>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="allowCaseWithExistingContract" type="xsd:boolean">
</xsd:element>
<xsd:choice minOccurs="0">
<xsd:element name="validationError" type="mnp:ErrorType"/>
<xsd:element name="internalError" type="mnp:ErrorType"/>
<xsd:element name="businessError" type="mnp:ErrorType"/>
<xsd:element name="externalError" type="mnp:ErrorType"/>
</xsd:choice>
</xsd:sequence>
I tried to use jaxb binding customization :
<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc">
<jxb:globalBindings>
<xjc:simple />
</jxb:globalBindings>
</jxb:bindings>
I'm trying to avoid jaxb - xjc from generating my fields as a List<JAXBElement<?>> validationErrorsAndAllowCaseWithExistingContractsAndInternalErrors, is there anyway I could accomplish that?

I advise you to simplify the schema if possible. I would put the allowCaseWithNewContract and allowCaseWithExistingContract as attributes in the enclosing element. I guess then, the remaining choice would have the type ErrorType.

I am not allowed to comment, but I believe this question has been solved here and here - basically your best shot is to use the JAXB2 Simplify Plugin as JAXB will prevent you from doing what you want as it wants the (de-)serialization to be consistent from XML to Java and back (i.e. you need to preserve the order).

Related

Not able to validate XSD for an XML with a namespace

I am not able to validate the XML using the below XSD,
<myTest>
<standardHeader xmlns="http://tow.gow.ho.com/2009/08/StandardHeader/">
<data>
<LEVELDATA>D2D</LEVELDATA>
</data>
</standardHeader>
</myTest>
XSD Data
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="myTest">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="standardHeader" minOccurs="0">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="data" minOccurs="0">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="LEVELDATA" minOccurs="0" type="xsd:normalizedString"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
I am getting the below error while validating this XSD with XML,
cvc-complex-type.2.4.a: Invalid content was found starting with element 'standardHeader'. One of '{standardHeader}' is expected.
How can I provide this standardHeader tag:
targetNamespace="http://tow.gow.ho.com/2009/08/StandardHeader/"
The problem is the wrong 'namespace' in the XML... (line 2)
When you remove it (or correct it) - it's correct.
Online-Validator
https://www.freeformatter.com/xml-validator-xsd.html
Sample XML-Generator (from XSD)
http://xsd2xml.com/
Namespace-Doc
https://www.w3schools.com/XML/xml_namespaces.asp
One possible solution for this problem is splitting the XSD into two files:
One for the first absent namespace (a.xsd) and one for the second namespace (b.xsd) which is declared by targetNamespace=... in b.xsd while a.xsd does not need that declaration. The second file with its own namespace is imported with the <xsd:import namespace="..." instruction. This namespace has also to be included in a namespace declaration of the xsd:schema element (here xmlns:std).
So a.xsd is:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema elementFormDefault="qualified"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:std="http://tow.gow.ho.com/2009/08/StandardHeader">
<xsd:import namespace="http://tow.gow.ho.com/2009/08/StandardHeader"
schemaLocation="b.xsd" />
<xsd:element name="myTest">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element ref="std:standardHeader" minOccurs="0">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
And b.xsd is:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema elementFormDefault="qualified"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://tow.gow.ho.com/2009/08/StandardHeader">
<xsd:element name="standardHeader">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="data" minOccurs="0">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="LEVELDATA" minOccurs="0" type="xsd:normalizedString"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
These two XSDs do validate your XML file with its namespace as it is.
This answer was inspired by this webpage: "Multi-Schema Project:
Zero, One, or Many Namespaces?". It does not copy the solutions 1-to-1, but is rather inspired by that webpage.

'OR' operation on element type in XSD

This is a continuity of My question
Assume below is my xsd file,
Updated XSD file
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/wm" xmlns="http://www.example.com/wm" elementFormDefault="qualified" version="1.0">
<xsd:include schemaLocation="Comm.xsd" />
<xsd:element name="testEame1">
<xsd:annotation>
<xsd:documentation> test </xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="id" type="xsd:string" minOccurs="1" />
<xsd:element name="session" type="rawSess" minOccurs="1" />
</xsd:sequence>
<xsd:attribute name="pid" type="xsd:integer" use="required" />
<xsd:attribute name="version" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:schema>
references another XSD which has type defined,
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" targetNamespace="http://www.example.com/wm" xmlns="http://www.example.com/wm" elementFormDefault="qualified">
<xsd:complexType name="rawSess">
<xsd:sequence>
<xsd:element name="oldSessionVersion" type="Sessiontype1" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="sessInfo">
<xsd:sequence>
<xsd:element name="newSessionVersion" type="Sessiontype2" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Sessiontype1">
<xsd:sequence>
<xsd:element name="ele1" type="xsd:string" minOccurs="0" />
<xsd:element name="ele2" type="xsd:string" />
<xsd:element name="ele3" type="xsd:string" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Sessiontype2">
<xsd:sequence>
<xsd:element name="nele1" type="xsd:integer" minOccurs="0" />
<xsd:element name="nele2" type="xsd:integer" />
<xsd:element name="nele3" type="xsd:integer" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
In the above xml, for element session , I want it to have only two types like below. Either sessInfo or rawSess
<xsd:element name="session" type='sessInfo| rawSess' minOccurs="1"/>
Update Note : userDefinedtypes are complex types.
How can I configure my xsd to achieve this
If userDefinedType1 and userDefinedType2 are simple atomic types, then define a union type:
<xs:element name="session" type="one-or-two"/>
<xs:simpleType name="one-or-two">
<xs:union memberTypes="userDefinedType1 userDefinedType2"/>
</xs:simpleType>
We now know that they are actually complex types. Define a type
<xs:complexType name="eitherType">
<xs:choice>
<xs:sequence>... content model of alternative 1</xs:sequence>
<xs:sequence>... content model of alternative 2</xs:sequence>
</xs:choice>
</xs:complexType>
and reference this type from the element declaration.
NB: this only works if there is no ambiguity, that is, if the validator can work out which branch of the choice to take based on the first element name that it sees in the instance document. If your choice were between two content models that both start with an h1 element, for example, you would have to reorganise the content models to remove the ambiguity.

JaxB property value is already defined. Use <jaxb:property> to resolve this conflict

I am using the following xsd schema file to generate java classes
<xsd:complexType name="Instruction">
<xsd:choice>
<xsd:sequence>
<xsd:element name="InstructionIndicator" type="InstructionIndicator">
<xsd:annotation>
<xsd:documentation>some text</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:sequence minOccurs="0" maxOccurs="49">
<xsd:element name="MultipleTimingModifier" type="ANDOR"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>some text</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="TimingAndDuration" type="TimingAndDuration" />
</xsd:sequence>
</xsd:sequence>
<xsd:sequence>
<xsd:choice>
<xsd:element name="AdministrationIndicator" type="AdministrationIndicator">
<xsd:annotation>
<xsd:documentation>some text</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:sequence>
<xsd:element name="DoseAdministration" type="DoseAdministration" />
<xsd:element name="TimingAndDuration" type="TimingAndDuration">
<xsd:annotation>
<xsd:documentation>some text</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:sequence minOccurs="0" maxOccurs="49">
<xsd:element name="MultipleTimingModifier" type="ANDOR"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>some text</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="TimingAndDuration" type="TimingAndDuration" />
</xsd:sequence>
</xsd:sequence>
</xsd:choice>
<xsd:sequence minOccurs="0">
<xsd:element name="IndicationForUse" type="Indication"
maxOccurs="50">
<xsd:annotation>
<xsd:documentation>some text</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="IndicationClarifyingFreeText" type="an1..255"
minOccurs="0" />
</xsd:sequence>
<xsd:element name="MaximumDoseRestriction" type="MaximumDoseRestriction"
minOccurs="0" maxOccurs="50">
<xsd:annotation>
<xsd:documentation>some text</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
But processing this results in an error
Property "MultipleTimingModifierAndTimingAndDuration" is already defined. Use <jaxb:property> to resolve this conflict.
To resolve this i wrote a binding file with following content
<jaxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc" version="2.0">
<jaxb:bindings schemaLocation="structures.xsd"
node="//xs:complexType[#name='Instruction']/xs:choice[1]
/xs:sequence[1]/xs:sequence/xs:element[#name='MultipleTimingModifier']">
<jaxb:property name="MultipleTimingModifier1" />
</jaxb:bindings>
<jaxb:bindings schemaLocation="structures.xsd"
node="//xs:complexType[#name='Instruction']/xs:choice
/xs:sequence[1]/xs:sequence/xs:element[#name='TimingAndDuration']">
<jaxb:property name="TimingAndDuration1" />
</jaxb:bindings>
</jaxb:bindings>
after adding this binding file while generating Jaxb classes in elcipse the following error is produced
compiler was unable to honor this property customization. It is attached to a wrong place, or its inconsistent with other bindings.
the classes will successfully generate if maxoccurs="49" constraint is removed from targeted sequence node
Note:
the schema is a combination of 5 different files and is of more then 2000 lines
only the part in which error is produced is shared here
Using the following binding code i have resolved my issue
<jaxb:bindings
schemaLocation="structures.xsd"
node="//xs:complexType[#name='Instruction']/xs:choice/xs:sequence[1]/xs:sequence[1]">
<jaxb:property name="seq1"/>
</jaxb:bindings>

The prefix "xsd" for element "xsd:element" is not bound. [11]

So I have a task to complete for Friday involving creating a shares system and I'm completely lost in Netbeans. I've used it once before and did reasonably well but I've been stuck on this same issue for 2 hours now.
I've obviously gotta create the XML and accompanying schema for this project but started from a blank XSD now, I can't validate the code and also have troubles to create the constrained XML document from the XSD as there isn't a primary Element. If anyone could point me in the right direction that would be a great help. Me and Netbeans do not seem to get along. The XSD is as follows and yes, it's probably something completely obvious.
<xs:schema version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:element name="shares">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CompanyName" type="xsd:string"/>
<xsd:element name="CompanySymbol" type="xsd:string"/>
<xsd:element name="AvailableShares" type="xsd:string"/>
<xsd:element name="Updated" type="xsd:date"/>
<xsd:complexType>
<xsd:element name="Currency" type="xsd:float"/>
<xsd:element name="Value" type="xsd:float"/>
</xsd:complexType>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
The xml only declared the namespace xmlns:xs="http://www.w3.org/2001/XMLSchema" but uses instead the prefix xsd.
Also the closing </xsd:schema> is missing.
Here is the fixed xml:
<xsd:schema version="1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:element name="shares">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CompanyName" type="xsd:string"/>
<xsd:element name="CompanySymbol" type="xsd:string"/>
<xsd:element name="AvailableShares" type="xsd:string"/>
<xsd:element name="Updated" type="xsd:date"/>
<xsd:complexType>
<xsd:element name="Currency" type="xsd:float"/>
<xsd:element name="Value" type="xsd:float"/>
</xsd:complexType>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>

Dealing with JAXB Collections

I am trying to unmarshall the following XML using JAXB:
<Works>
<Work>
<Composers>
<Composer>
<Name>A name</Name>
</Composer>
<Composer>
<Name>A name 2</Name>
</Composer>
</Composers>
</Work>
</Works>
I have generated all of the classes using XJC. If I want to access the Composers collection, I have to do this:
List<Composer> composers = work.getComposers().getComposer();
Is there any way I can do the following instead?
List<Composer> composers = work.getComposers();
I appreciate the need for a Composers object as it derived from the XML, but when dealing in Java, having an intermediate POJO that stores the collections seems a bit redundant.
My XSD is:
<xsd:complexType name="Works">
<xsd:sequence>
<xsd:element name="Work" type="Work" maxOccurs="unbounded" minOccurs="0"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Work">
<xsd:sequence>
<xsd:element name="Composers" type="Composers"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Composers">
<xsd:sequence>
<xsd:element name="Composer" type="Composer" maxOccurs="unbounded" minOccurs="0"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Composer">
<xsd:sequence>
<xsd:element name="Name" type="xsd:string"></xsd:element>
</xsd:sequence>
</xsd:complexType>
The #XmlElementWrapper plugin does exactly what you want.
For anybody who can not or does not want to use the plugin:
If you can live with a different XML structure, it's possible to avoid generating the extra wrapper classes by simply using maxoccurs="unbounded" and leaving out the containing element. Using the original example:
<xsd:element name="Work" type="Work" maxOccurs="unbounded" minOccurs="0"/>
<xsd:complexType name="Work">
<xsd:sequence>
<xsd:element name="Composer" type="Composer" maxOccurs="unbounded" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Composer">
<xsd:sequence>
<xsd:element name="Name" type="xsd:string"></xsd:element>
</xsd:sequence>
</xsd:complexType>
will produce a structure like this:
<Work>
<Composer>
<Name>A name</Name>
</Composer>
<Composer>
<Name>A name 2</Name>
</Composer>
</Work>
This will put a method on the Work type that returns a List<Composer> object. Unfortunately the method is called getComposer instead of getComposers, but you can use annotations or custom bindings to fix that problem.

Categories