I am trying to use JAXB to convert xsd schema to java classes. Unfortunately I do have an issue. The xsd which casues problem is:
<xs:complexType name="AdditionalDataType">
<xs:sequence>
<xs:element name="AvailabilityStatus" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="AvailabilityStatus" maxOccurs="999">
<xs:complexType>
<xs:attributeGroup ref="IdentifierGrp"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
The error I get is
[ERROR] \target\generated-sources\AdditionalDataType.java:[1012,22] AdditionalDataType.AvailabilityStatus is already defined in AdditionalDataType
I found this How to override the default name for in JAXB using a external binding file?
but when I tried to solve it with the following bindings:
<jxb:bindings node="//xs:complexType[#name='AdditionalDataType']//xs:sequence//xs:element[#name='AvailabilityStatus']//xs:complexType//xs:sequence//xs:element[#name='AvailabilityStatus']">
<jxb:property name="AvailabilityStatusSA"/>
</jxb:bindings>
it didn't help, it didn't change anything.
Can someone please help ?
#Ekrem
I cannot modify the xml, I would do it but I cannot. I need to have AdditionalDataType which has a List of AvailabilityStatus
I dont care if the inner AvailabilityStatus (the one I am trying to map to AvailabilityStatusSA) will be an inner class or not.
Change
<jxb:property name="AvailabilityStatusSA"/> to <jxb:class name="AvailabilityStatusSA"/> and your binding node path should end with complexType -><jxb:bindings node=...[#name='AvailabilityStatus']xs:complexType"
so your external binding file should look like this:
<jxb:bindings node="//xs:complexType[#name='AdditionalDataType']//xs:sequence//xs:element[#name='AvailabilityStatus']//xs:complexType//xs:sequence//xs:element[#name='AvailabilityStatus']//xs:complexType">
<jxb:class name="AvailabilityStatusSA"/>
</jxb:bindings>
Related
I have a schema with two elements within a <xs:choice/> block, as per the following fragment:
<xs:complexType name="POCD_MT000040.Component2">
<xs:sequence>
<xs:element name="realmCode" type="CS" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="typeId" type="POCD_MT000040.InfrastructureRoot.typeId" minOccurs="0"/>
<xs:element name="templateId" type="II" minOccurs="0" maxOccurs="unbounded"/>
<xs:choice>
<xs:element name="nonXMLBody" type="POCD_MT000040.NonXMLBody"/>
<xs:element name="structuredBody" type="POCD_MT000040.StructuredBody"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="nullFlavor" type="NullFlavor" use="optional"/>
<xs:attribute name="typeCode" type="ActRelationshipHasComponent" use="optional" fixed="COMP"/>
<xs:attribute name="contextConductionInd" type="bl" use="optional" fixed="true"/>
</xs:complexType>
This is part of the HL7/CDA specification schemas, by the way.
Well, I am using maven-jaxb2-plugin to generate the Java classes, with a touch of the jaxb2-basics plugin to simplify complex elements, like nonXMLBody and structuredBody. Let's say I have a bindings file with the following contents:
<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"
xmlns:simplify="http://jaxb2-commons.dev.java.net/basic/simplify"
jxb:extensionBindingPrefixes="xjc simplify"
version="2.1">
<jxb:globalBindings
typesafeEnumMaxMembers="1000"
generateMixedExtensions="true"
generateIsSetMethod="true"
choiceContentProperty="true">
<xjc:serializable uid="1" />
</jxb:globalBindings>
<jxb:bindings schemaLocation="xsd/POCD_MT000040.xsd">
<jxb:bindings node="xs:complexType[#name='POCD_MT000040.Component2']//xs:choice">
<simplify:as-element-property />
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
The attributes are generated as expected:
protected POCDMT000040NonXMLBody nonXMLBody;
protected POCDMT000040StructuredBody structuredBody;
However, although I am using generateIsSetMethod="true" in the global bindings, the methods isSetNonXMLBody ( ) and isSetStructuredBody ( ) are not being generated at all. The equivalent methods for the rest of the attributes are present, though, like isSetTypeId ( ).
Am I missing any option I should know of to generate these methods in the aforementioned elements?
I'm converting an XSD schema to a Java annotated bean for Hibernate with HyperJaxb3.
So far I managed to generate the Java objects, but I need to customize the remark field of the OperableType because the default generated length is 255 and I need to extend it to 4000.
Here's the fragment of the relevent xsd schema:
<xs:complexType name="OperableType" abstract="true">
<xs:annotation>
<xs:documentation xml:lang="en">OperableType contains all the elements and attributes common to all the operables. This is an abstract type, so no element of this type will be present in the XML.
The logical ID is a unique logical identifier of a sanctioned entity, of a regulation or of a detail of a sanction entity. This information is also provided to external actors for help, especially when entity multiple aliases make it difficult the identification task. For entities imported from previous database, the old value is retained.</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="remark" type="fsdexport:UnlimitedTextType" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="additionalInformation" type="fsdexport:AdditionalInfoType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="logicalId" type="xs:long" use="required"/>
</xs:complexType>
<xs:simpleType name="UnlimitedTextType">
<xs:restriction base="xs:string"/>
</xs:simpleType>
I can't modify the XSD schema nor the XML file I receive, so I need to customize the bindings for it to work.
I tried using this binding
<jxb:bindings node="xs:complexType[#name='OperableType']">
<jxb:bindings node="xs:sequence//xs:element[#name='remark']">
<hj:basic>
<orm:column length="4000" />
</hj:basic>
</jxb:bindings>
</jxb:bindings>
but it doesn't modify the length in the generated code.
#ElementCollection
#OrderColumn(name = "HJINDEX")
#Column(name = "HJVALUE", length = 255)
#CollectionTable(name = "OPERABLE_TYPE_REMARK", joinColumns = {
#JoinColumn(name = "HJID")
})
public List<String> getRemark() {
I also tried to use 'hj:default-single-property' to customized the UnlimitedTextType but I didn't managed to make it work either.
After asking from help from the source,
https://github.com/highsource/hyperjaxb3/issues/54, I have the answer:
<jxb:bindings node="xs:complexType[#name='OperableType']">
<jxb:bindings node="xs:sequence//xs:element[#name='remark']">
<hj:element-collection>
<orm:column length="4000" />
</hj:element-collection>
</jxb:bindings>
</jxb:bindings>
The key is tu use hj:element-collection instead of hj:basic for an xml sequence.
I'm trying to generate classes from wsdl using jaxws-maven-plugin, but I get uncompilable results. The problem is this part of one of the xsds, where you can see that there are nested elements with the same name:
<xs:complexType name="TrafficCountsReplyData" abstract="true">
<xs:sequence>
<xs:element name="effectiveTrafficWindow" type="common:DateTimeMinutePeriod" minOccurs="1" maxOccurs="1"/>
<xs:element name="flows" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="item" type="flow:Flow" minOccurs="0" maxOccurs="100"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="counts" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="item" minOccurs="0" maxOccurs="1440">
<xs:complexType>
<xs:sequence>
<xs:element name="key" type="common:DateTimeMinutePeriod" minOccurs="1"
maxOccurs="1"/>
<xs:element name="value" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="item" minOccurs="1" maxOccurs="3">
<xs:complexType>
<xs:sequence>
<xs:element name="key" type="flight:TrafficType"
minOccurs="1" maxOccurs="1"/>
<xs:element name="value" type="flow:Counts" minOccurs="1"
maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
As you can see, there there are multiple elements named item. This result in multiple inner classes with the same name inside of the single class TrafficCountsReplyData
So I'm trying to put together a binding file which would rename one of them. When I try to rename the outer item in the counts element using this:
<jaxb:bindings node="//xs:complexType[#name='TrafficCountsReplyData']//xs:element[#name='counts']//xs:element[#name='item']">
<jaxb:class name="Lulz"/>
</jaxb:bindings>
I get the following error:
[ERROR] XPath evaluation of "//xs:complexType[#name='TrafficCountsReplyData']//xs:element[#name='counts']//xs:element[#name='item']" results in too many (2) target nodes
When I create the binding xpath expression for the inner one like this:
<jaxb:bindings node="//xs:complexType[#name='TrafficCountsReplyData']//xs:element[#name='counts']//xs:element[#name='item']//xs:element[#name='value']//xs:element[#name='item']">
Then I get following error:
java.lang.IllegalArgumentException: Illegal class inheritance loop. Outer class Lulz may not subclass from inner class: Lulz
I can't figure out how to make this work. Where does the inheritance come from? There's another item in the flows element, but that shouldn't be matched by the Xpath. Without the binding file, I can generate the sources. I have correct schema in the binding file, because I can for example rename the class generated by the parent element.
mmm
I had a similar issue, but with properties..
I don't ahve the full xsd to check, but provided you want to change the OUTER item tag into something else, try this one:
<?xml version="1.0"?>
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="../yourlocation/yourschema.xsd" version="1.0">
<!-- Customise the package name -->
<jxb:schemaBindings>
<jxb:package name="whatyouwant.something"/>
</jxb:schemaBindings>
<!-- rename the value element -->
<jxb:bindings node="//xs:complexType[#name='TrafficCountsReplyData']//xs:sequence//xs:element[#name='counts']//xs:complexType//xs:sequence//xs:element[#name='item']">
<jaxb:class name="Lulz"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
If this seems not to work if you can disclose the xml I should be able to help you furthe (on vacation until monday in case) , but consider that you were giving the wrong "path", jumping away a few "subelement" in your xpath expression.
Let me know.
I've found the solution here: JAXB Customizations With a Poorly Formed WSDL
I had to add /xs:complexType at the end of the Xpath. I guess it's because the root of the class is in fact the complexType and not enclosing xs:element. So it was like this:
<jaxb:bindings node="//xs:complexType[#name='TrafficCountsReplyData']//xs:element[#name='counts']/xs:complexType/xs:sequence/xs:element[#name='item']/xs:complexType">
<jaxb:class name="Lulz"/>
</jaxb:bindings>
Now I can generate classes and compile them.
In JAXB when using automatic class generation via xjc from xsd scheme.
alpha.xsd
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="alpha">
<xs:complexType>
<xs:sequence>
<xs:element name="persons">
<xs:complexType>
<xs:sequence>
<xs:element name="person" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
beta.xml
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="country">
<xs:complexType>
<xs:sequence>
<xs:element name="class">
<xs:complexType>
<xs:sequence>
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
As you can see there is Person element which is shared among these two schemes. What I would like to do is:
generate classes using xjc in a way that ObjectFactory class is shared for both schema classes (the output classes will be in one package)
not use nested static classes (with attribute localScoping="toplevel")
use Person class to bind with /alpha/persons/person as with /country/class/person so there are not two Person classes created
The purpose of this is unmarshalling one xml, applying business logic and creating another one as output where some elements (like Person) are same and shared for both xml files. The namespace will be the same for both files.
I would welcome if you can present me with complete .xjb bindings settings file. So far mine contains only:
<jxb:bindings version="1.0"
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:extensionBindingPrefixes="xjc">
<jxb:globalBindings localScoping="toplevel"/>
</jxb:bindings>
And of course I get name collision error as I do not know how to set binding compiler to see Person as the same entity/element.
You can use an external binding file to indicate that during class generation we wish to use our existing class for the complex type called Document.
binding.xml
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jxb:bindings schemaLocation="beta.xsd">
<jxb:bindings node="//xs:element[#name='person']/complexType">
<jxb:class ref="alpha.Person"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
XJC Call
xjc -b binding.xml beta.xsd
If namespace of person from A will be equals namespace person from B, that xjc has to generate the correct classes.
I use maven-jaxb2-plugin to generate jaxb annotated classes from xsd. I have many xsd files like those:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="A3">
<xs:complexType>
<xs:sequence>
<xs:element name="loginPartner">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="login"/>
<xs:element type="xs:string" name="password"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="A3">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="errorCode"/>
<xs:element type="xs:string" name="errorDescription"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
When I run maven plugin it gives me an error:
[ERROR] Error while parsing schema(s).Location [
file:schema1.xsd{10,16}]. org.xml.sax.SAXParseException: 'A3' is already
defined
Is there any way to fix this?
Actually I have many XSDs representing request/response messages to/from server. I want to simplify creating, validating, parsing messages. Maybe is there another solution for this?
I had a similar problem; I had two separate and independent WSDL (each with several schema definitions in each) that I was running through JAXB (via the maven-jaxb2-plugin) to generate mapping classes.
My WSDL's shared a duplicate schema definition that was causing XJC to choke.
Because they were both independent, I was able to generate JAXB mappings by running two separate executions of the maven-jaxb2-plugin - one for each WSDL (covered here - How can I tell jaxb / Maven to generate multiple schema packages?).
You cannot have conflicting element definitions within the same namespace. This is same as not allowing multiple classes with the same name in a given package in Java. Your best bet is to define them with different names or in different namespaces.
you can rename the second or the first A3 of your xsd in your jaxb binding file
<jaxb:bindings schemaLocation="filePath.xsd" node="/xs:schema">
<jaxb:bindings node="//xs:element[#name='A3']">
<jaxb:property name="SecondA3"/>
</jaxb:bindings>
</jaxb:bindings>