Using java 1.8, maven-jaxb2-plugin:0.14.0, and JAXB 2.3.0
when I generate java classes from XSD files, and some classes are too simple, JAXB decides to skip them. Instead, it puts a #XmlElementWrapper annotation.
Example:
<xs:complexType name="AAAA">
<xs:sequence>
<xs:element name="eeee" type="BBBB" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
Turns into
#XmlElementWrapper(namespace = ...)
#XmlElement(namespace = ....)
protected List<BBBB> eeee;
in the logs, I see:
[INFO] Replacing field [eeee AAAA]
In this particular care this optimization does not help me, I would prefer to see the classes as I designed the XSD (eg. AAAA turned into a Java class).
Is there a way to force JAXB into generating all classes and stop running "Replacing field" step?
I'm not sure that I understand correctly. It will be better if you publicate full xsd model and original generated java class/expected class.
But, may be using refernce will help you
<xs:complexType name="AAAA">
<xs:sequence>
<xsd:element ref="eeee" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="eeee">
<xs:sequence>
<xs:element name="eeee" type="BBBB" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
Related
I have a question regarding the correct usage of the Citrus validation matchers. In the official XML example there is the following XSD schema (TodoList.xsd) defined for a getTodoListResponse:
<xs:element name="getTodoListResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="list">
<xs:complexType>
<xs:sequence>
<xs:element name="todoEntry" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="description" type="xs:string" minOccurs="0"/>
<xs:element name="attachment" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="cid" type="xs:string"/>
<xs:element name="contentType" type="xs:string"/>
<xs:element name="data" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="done" type="xs:boolean" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
The validation matcher that is defined looks like this (templates/getTodoListResponse.xml):
<todo:getTodoListResponse xmlns:todo="http://citrusframework.org/samples/todolist">
<todo:list>
<todo:todoEntry>
<todo:id>#ignore#</todo:id>
<todo:title>${todoName}</todo:title>
<todo:description>${todoDescription}</todo:description>
</todo:todoEntry>
</todo:list>
</todo:getTodoListResponse>
But when running the test multiple times via mvn verify there are multiple todoEntry elements in the resulting XML. In order to check this variable list of XML elements that come back in the result. Therefore the check will fail.
The question is, if there is a way to express this dynamic list via the XML validation matcher API.
I got a working solution which is based on the groovy validator like this:
assert root.list.children().size() > 1 (getTodoListResponseValidator.groovy)
But I would rather like to see this working through the XML validation. It seems there is something similar called #matchesXml(), but from the docs it is not clear for me if this is suitable for the described use case.
Thx in advance.
Bye
Mario
Bottom line this is just a bad designed test for the todo-list demo. Integration tests should always operate on a well-known state of the application under test. And the tests should always leave a clean state for other tests to come. These principles are violated in that particular sample.
In fact the sample that you mention is just a demo and therefore not written as a full qualified real world example. Following from that the tests are not working when executed multiple times.
To fix this I would recommend to clear the todo list in a before-test step so you always operate on an empty list. Another possibility would be to use XPath validation instead of comparing the complete list of entries. The XPath validation can check the amount of list entries to be greater that zero for instance (just like you did in the groovy script).
In addition to that you could write a XPath expression that only validates the last entry in that list of todos returned by the server. Something like that
<validate path="count(//todo:todoEntry)" value="#greaterThan(0)#" result-type="number"/>
<validate path="//todo:todoEntry[last()]/todo:title" value="${todoName}"></validate>
I'm going to generate java code from the xsd. I want to know how to remove xsd element when converting xsd to java using jaxb. My goal is to ignore message
Ex:
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:string" name="message"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Java Variables
#XmlElement
protected String name;
In here you can see that message element got removed. I want to know how to do that?
If I understand you correctly, to sum it up you want to ignore a mandatory element and still want the result to validate correctly. My short answer is that this is contradictory and does not make sense. JAXB is built to do it correctly and you want do it wrongly(?).
You have several options, eg.
Live with the extra constructor argument.
Generate no-arg constructor instead.
Don't generate, but hand code JAXB annotated classes. Maybe turn off some validation.
Don't use JAXB, use something else (dom4j et. al.) or handcraft the xml
Possibly you can add some overriding in a binding file or even a plug-in, but I wouldn't think it was worth it.
Can you alter the .xsd ?
The current Element "note" tells that both "name" and "message" are mandatory. If you want "message" to be conditional you probably need to add minOccurs="0" attribute:
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:string" name="message" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
We have the following problem. We try to generate Java code from XSD files that contain group declarations and multiple group references to these group declarations. Here a simplified version:
<xs:group name="Information">
<xs:sequence>
<xs:element name="Name">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="updated" type="xs:boolean"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:group>
<xs:element name="Address">
<xs:complexType>
<xs:sequence>
<xs:group ref="Information" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Customer">
<xs:complexType>
<xs:sequence>
<xs:group ref="Information"/>
</xs:sequence>
</xs:complexType>
</xs:element>
The main points are:
Each of these elements is defined in its own file
The same group Information is references twice
There is no separate type for the group
There is also no separate type for the Name element inside the group
We cannot change the XSD file
The problem we face now is that xjc generates non-deterministically depending on the machine where we build, sometimes the type Address.Name and sometimes the type Customer.Name, because the Name element is a complex type and requires a type.
Is there any way to tell xjc to always generate the same type?
Customize the anonymous complex type with the jaxb:class binding and specify the class name.
Use <jaxb:globalBindings localScoping="toplevel"/> to generate inner classes on the top level instead.
A combination of these two will give you a predictable class.
You could try the -episode command line option of XJC. It is primarily meant for compilation in multiple steps, but I think it basically "dumps decisions" taken by XJC during a compilation into a (binding) configuration file. If you are lucky, you find suitable settings related to the Name element/type in the episode file which you can copy into your binding configuration file to make XJC behave deterministically.
In a WSDL file, there is an xs:any element that I want to override from:
<xs:element minOccurs="0" maxOccurs="1" name="GetPermissionCollectionResult">
<xs:complexType mixed="true">
<xs:sequence>
<xs:any/>
</xs:sequence>
</xs:complexType>
</xs:element>
To:
<xs:element minOccurs="0" maxOccurs="1" name="GetPermissionCollectionResult">
<xs:complexType mixed="true">
<xs:sequence>
<xs:any processContents="skip"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Ultimately what I'm doing is using JAXB to generate annotated Java code from the WSDL. And for the xs:any element, this is generated:
#XmlAnyElement(lax = true)
Instead I want this:
#XmlAnyElement(lax = false)
The WSDL file is not generated by me so I can't just make the modification to the file. Is there a way of using a JAXB binding file to get the same effect?
I looked at using jaxb:property and jaxb:class elements but neither seems to fit want I want done.
I'm generating an object which has an XSD schema
<xs:element name="roleAssignments" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="roleAssignment" type="tns:roleAssignmentDataObj" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
but which generates Java code as
protected ProjectDataObj.RoleAssignments roleAssignments;
I'm trying to get it generate
protected List<RoleAssignment> roleAssignments;
I've tried fiddling around with xjb binding for wsimport but that hasn't seemed to give me the control I want. Is there a way to do this?
It turns out I needed to use a plug-in to XJC.
I used https://github.com/dmak/jaxb-xew-plugin. This plug-in will correctly generate the correct wrappers on the client side.
Have you tried XJC?
Here is more reference:
http://theopentutorials.com/examples/java/jaxb/generate-java-class-from-xml-schema-using-jaxb-xjc-command/