I am trying to generate java stubs from a large set of schemas (15k lines total) using Axis2 wsdl2java and have encountered a problem with the following complex type. Originally when running the tool on my schema files I received an nondescript error message, "unsupported content Simple Content !" To find the cause of this error I downloaded and deployed the Axis2 project from source, found the error string and examined the element causing the problem.
I believe the source of the problem relates to nesting a complex type with simple content inside simple content.
I have two examples, SequencedTextType, which fails, and OpenTextType, which succeeds. Both types have content that are extensions of TextType. This should make it easier to spot the problem and provide an explaination.
The failing SequencedTextType:
<xs:element name="Reason" type="SequencedTextType" id="oagis-id-fa892eb1e28c46088bc50394c62a8655"/>
<xs:complexType name="SequencedTextType" id="oagis-id-51e010d7a1e24ebe89fcf58989fefd1b">
<xs:complexContent>
<xs:extension base="TextType">
<xs:attribute name="sequenceNumber" type="NumberType_B98233" id="oagis-id-39a5a53826024a65a2291f50d9feecd3"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="NumberType_B98233" id="oagis-id-d614ed8726ff482c9c5a8183d735d9ed">
<xs:restriction base="xs:integer"/>
</xs:simpleType>
The passing OpenTextType:
<xs:complexType name="OpenTextType" id="oagis-id-5840f7a57dd949ababcd1eb394b2840c">
<xs:simpleContent>
<xs:extension base="TextType">
<xs:attribute name="typeCode" type="CodeType_1E7368" id="oagis-id-2780e69800934662a4782be31c2bacf6"
use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="CodeType_1E7368" id="oagis-id-d2f721a297684b538e7dbb88cf5526bc">
<xs:restriction base="xs:token"/>
</xs:simpleType>
The shared TextType:
<xs:complexType name="TextType" id="oagis-id-d97b8cf6a26f408db148163485796d15">
<xs:simpleContent>
<xs:extension base="TextType_62S0B4"/>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="TextType_62S0B4" id="oagis-id-89be97039be04d6f9cfda107d75926b4">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="languageCode" type="clm56392A20081107_LanguageCodeContentType" id="oagis-id-c8d0c7094d7d4fbeb7e50fd20a17c1b3" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="clm56392A20081107_LanguageCodeContentType" id="oagis-id-c5e8ac8c44894e54a147a870136da686">
<xs:restriction base="xs:normalizedString"/>
</xs:simpleType>
The Axis2 method:
private void copyMetaInfoHierarchy(BeanWriterMetaInfoHolder metaInfHolder,
QName baseTypeName,
XmlSchema parentSchema)
throws SchemaCompilationException {
//... Code omitted for clarity
// see whether this type is also extended from some other type first
// if so proceed to set their parents as well.
if (type instanceof XmlSchemaComplexType) {
XmlSchemaComplexType complexType = (XmlSchemaComplexType) type;
if (complexType.getContentModel() != null) {
XmlSchemaContentModel content = complexType.getContentModel();
if (content instanceof XmlSchemaComplexContent) {
//continue recursion
} else if (content instanceof XmlSchemaSimpleContent) {
/***** TextType throws error in this branch *****/
throw new SchemaCompilationException(
SchemaCompilerMessages.getMessage("schema.unsupportedcontenterror", "Simple Content"));
} else {
throw new SchemaCompilationException(
SchemaCompilerMessages.getMessage("schema.unknowncontenterror"));
}
}
//Do the actual parent setting
metaInfHolder.setAsParent(baseMetaInfoHolder);
}
//... Code omitted for clarity
}
And here is the relevant error message:
Caused by: org.apache.axis2.schema.SchemaCompilationException: Unsupported content Simple Content !
at org.apache.axis2.schema.SchemaCompiler.copyMetaInfoHierarchy(SchemaCompiler.java:1396)
at org.apache.axis2.schema.SchemaCompiler.processComplexContent(SchemaCompiler.java:1279)
at org.apache.axis2.schema.SchemaCompiler.processContentModel(SchemaCompiler.java:1228)
at org.apache.axis2.schema.SchemaCompiler.processComplexType(SchemaCompiler.java:1172)
at org.apache.axis2.schema.SchemaCompiler.processNamedComplexSchemaType(SchemaCompiler.java:1092)
at org.apache.axis2.schema.SchemaCompiler.processSchema(SchemaCompiler.java:1006)
at org.apache.axis2.schema.SchemaCompiler.processElement(SchemaCompiler.java:772)
at org.apache.axis2.schema.SchemaCompiler.processElement(SchemaCompiler.java:604)
at org.apache.axis2.schema.SchemaCompiler.process(SchemaCompiler.java:2052)
at org.apache.axis2.schema.SchemaCompiler.processParticle(SchemaCompiler.java:1935)
at org.apache.axis2.schema.SchemaCompiler.processComplexContent(SchemaCompiler.java:1283)
at org.apache.axis2.schema.SchemaCompiler.processContentModel(SchemaCompiler.java:1228)
at org.apache.axis2.schema.SchemaCompiler.processComplexType(SchemaCompiler.java:1172)
at org.apache.axis2.schema.SchemaCompiler.processNamedComplexSchemaType(SchemaCompiler.java:1092)
at org.apache.axis2.schema.SchemaCompiler.processComplexContent(SchemaCompiler.java:1261)
at org.apache.axis2.schema.SchemaCompiler.processContentModel(SchemaCompiler.java:1228)
at org.apache.axis2.schema.SchemaCompiler.processComplexType(SchemaCompiler.java:1172)
at org.apache.axis2.schema.SchemaCompiler.processNamedComplexSchemaType(SchemaCompiler.java:1092)
at org.apache.axis2.schema.SchemaCompiler.processSchema(SchemaCompiler.java:1006)
at org.apache.axis2.schema.SchemaCompiler.processElement(SchemaCompiler.java:645)
at org.apache.axis2.schema.SchemaCompiler.processElement(SchemaCompiler.java:615)
at org.apache.axis2.schema.SchemaCompiler.compile(SchemaCompiler.java:423)
at org.apache.axis2.schema.SchemaCompiler.compile(SchemaCompiler.java:292)
at org.apache.axis2.schema.ExtensionUtility.invoke(ExtensionUtility.java:102)
I am hoping for some insight into why OpenTextType can pass through the attached Axis2 method and why SequencedTextType cannot. Thank you.
I'm not really sure why it happens like that.
But, I found solution from this link
It worked for me when I add -d xmlbeans while using wsdl2java command
The default binding is adb and it has some issue with this Simple Content.
It seems this has been fixed in Axis2 1.7.x versions.
Related
My Issue
I am using the jaxb2 maven plugin to convert my XSD defined objects into Java classes. My goal is to set a list type element in my XSD (such as xs:choice unbound), to LinkedList instead of using the default ArrayList type. I am using the jaxb-xew-plugin version 1.10. Here is my relevant code:
XSD:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema jaxb:version="2.0"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xew="http://github.com/jaxb-xew-plugin"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
jaxb:extensionBindingPrefixes="xew"
elementFormDefault="qualified">
<xs:element name="TEST">
<xs:complexType>
<xs:annotation>
<xs:appinfo>
<xew:xew collection="java.util.LinkedList"
collectionInterface="java.util.List"
instantiate="lazy"
plural="true"/>
</xs:appinfo>
</xs:annotation>
<xs:choice>
<xs:element name="action" type="xs:token" minOccurs="0" maxOccurs="unbounded">
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
POM:
<build>
<resources>
<resource>
<directory>src/main/xsd</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.5.0</version>
<executions>
<execution>
<id>xjc</id>
<phase>generate-sources</phase>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<sources>src/main/xsd</sources>
<packageName>com.tug.data.model.gen</packageName>
<verbose>true</verbose>
<clearOutputDir>false</clearOutputDir>
<extension>true</extension>
<arguments>
<argument>-Xsetters</argument>
<argument>-Xxew</argument>
<argument>-Xfluent-api</argument>
<argument>-Xjaxbindex</argument>
<argument>-Xequals</argument>
<argument>-XhashCode</argument>
<argument>-XtoString</argument>
<argument>-Xcopyable</argument>
<argument>-Xmergeable</argument>
</arguments>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.github.jaxb-xew-plugin</groupId>
<artifactId>jaxb-xew-plugin</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>net.java.dev.jaxb2-commons</groupId>
<artifactId>jaxb-fluent-api</artifactId>
<version>2.1.8</version>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.12.0</version>
</dependency>
</dependencies>
</plugin>
Resulting Java code generated
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"action"
})
#XmlRootElement(name = "TEST")
public class TEST implements Cloneable, CopyTo2, Equals2, HashCode2, MergeFrom2, ToString2
{
#XmlElement(required = true)
protected List<Action> action;
public List<Action> getAction() {
if (action == null) {
action = new ArrayList<Action>(); // <--- **This should have been LinkedList**
}
return this.action;
}
As you can see, the ArrayList type is still coming out instead of LinkedList. It actually seems like the xew arguments and commands are being ignored entirely... I don't get any errors
I have tried many variations of this, copying and pasting the xs:annotation blurb pretty much in every combination of locations I could logically think of. The only error I get is here:
<xs:element name="TEST">
<xs:complexType>
<xs:choice>
<xs:element name="action" type="xs:token" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:appinfo>
<xew:xew collection="java.util.LinkedList"
collectionInterface="java.util.List"
instantiate="lazy"
plural="true"/>
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
This combo results in: com.sun.istack.SAXParseException2: compiler was unable to honor this xew customization. It is attached to a wrong place, or its inconsistent with other bindings.
Do you see any missing step which would result in my custom collection override would not be picked up on?
I attached the maven debug output, it is a lot to look through and I don't pick up any hints there.
mvn-debug.log
Or...
Is there another way to use a custom List type when generating my Java objects from XSD?
(PS. I cross-posted this on the github section for the jaxb-xew-plugin, however I realized the last commit was over 2 years ago so it may be a dormant project. Posting here for help in the SOF community)
In the scope of the XSD that you have provided the customization does make sense. You need to understand the role of Xew plugin: if type A has some filed which is complex like type TEST in our example, then we have a "matroska" A→TEST→List, and in this case plugin tries to remove type TEST from the model.
Now you have provided only TEST in your example, this is only half of the story, the plugin does not do anything in this case. You need also to provide another type A that uses TEST, for example:
<xs:element name="A">
<xs:complexType>
<xs:sequence>
<xs:element ref="TEST">
<xs:annotation>
<xs:appinfo>
<xew:xew collection="java.util.LinkedList"
collectionInterface="java.util.List"
instantiate="lazy"
plural="true"/>
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="TEST">
<xs:complexType>
<xs:sequence>
<xs:element name="action" type="xs:token" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
And that is where plugin is powered on. You will see in the output:
[INFO] Modifications:
[INFO] Replacing field [TEST com.tug.data.model.gen.A#test]
[INFO] 1 modification(s) to original code.
[INFO]
[INFO] Deletions:
[INFO] Removing class com.tug.data.model.gen.TEST from package com.tug.data.model.gen
[INFO] Removing factory method [com.tug.data.model.gen.TEST#createTEST()] from com.tug.data.model.gen.ObjectFactory
[INFO] 2 deletion(s) from original code.
and the resulting class will be (I removed unrelated staff):
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"tests"
})
#XmlRootElement(name = "A")
public class A implements Cloneable, CopyTo2, Equals2, HashCode2, MergeFrom2, ToString2
{
#XmlElementWrapper(name = "TEST", required = true)
#XmlElement(name = "action")
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
protected List<String> tests;
public List<String> getTESTS() {
if (tests == null) {
tests = new LinkedList<String>();
}
return tests;
}
public void setTESTS(List<String> tests) {
this.tests = tests;
}
public A withTESTS(String... values) {
if (values!= null) {
for (String value: values) {
getTESTS().add(value);
}
}
return this;
}
public A withTESTS(Collection<String> values) {
if (values!= null) {
getTESTS().addAll(values);
}
return this;
}
public A withTESTS(List<String> tests) {
setTESTS(tests);
return this;
}
...
}
and that is where LinkedList pops up.
So plugin does not modify TEST type. Basically, the policy would be "remove or leave it alone". If you want to customize type TEST on its own, you need to use native JAXB customization collectionType:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema jaxb:version="2.0"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="TEST">
<xs:complexType>
<xs:sequence>
<xs:element name="action" type="xs:token" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:appinfo>
<jaxb:property collectionType="java.util.LinkedList" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
You have to customize the JAXB bindings. So in a directory of your project, say src/main/xjb, create a file like this (beware the collectionType):
<bindings version="2.0" xmlns="http://java.sun.com/xml/ns/jaxb">
<globalBindings collectionType="java.util.Linkedlist"/>
</bindings>
This will customize the Java type globally (for all elements in all schemas).
If you want to customize only for a specific element, e.g. the action element in your case, specify the schema location and XPath to the element like this instead (assuming the xsd is src/main/xsd folder for instance):
<bindings version="2.0" xmlns="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<bindings schemaLocation="../xsd/schema.xsd" node="//xs:element[#name='action']">
<property collectionType="java.util.LinkedList" />
</bindings>
</bindings>
Then use it in the jaxb2 maven plugin's configuration in your POM:
...
<configuration>
<sources>src/main/xsd</sources>
<xjbSources>
<xjbSource>src/main/xjb</xjbSource>
</xjbSources>
...
</configuration>
...
The XML schema is not modified and remains platform/language-independent as it is meant to be.
I have an XSD with some enumerated values as below. When XJC generates the enum of the corresponding element it generates like below. Could you please let me the customization required so that it generates enum as 5("05").
<xsd:simpleType name="CountyCodeEnumType">
<xsd:annotation>
<xsd:documentation>FL_CNTY_CD</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="01">
<xsd:annotation>
<xsd:documentation>Dade</xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="02">
<xsd:annotation>
<xsd:documentation>Duval</xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="03">
<xsd:annotation>
<xsd:documentation>Hillsborough</xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="04">
<xsd:annotation>
<xsd:documentation>Pinellas</xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>
Generated Java code
#XmlType(name = "CountyCodeEnumType")
#XmlEnum
public enum CountyCodeEnumType {
/**
* Dade
*
*/
#XmlEnumValue("01")
VALUE_1("01"),
/**
* Duval
*
*/
#XmlEnumValue("02")
VALUE_2("02"),
/**
* Hillsborough
*
*/
#XmlEnumValue("03")
VALUE_3("03"),
/**
* Pinellas
*
*/
#XmlEnumValue("04")
VALUE_4("04")
}
You can't name an enum value with a number. So 5("05") is technically not possible.
You can, however customize names of enum values using typesafeEnumMember binding. Here's an example:
<jaxb:bindings schemaLocation="ogc/gml/3.1.1/base/coverage.xsd" node="/xs:schema">
<jaxb:bindings node="xs:simpleType[#name='IncrementOrder']">
<jaxb:typesafeEnumClass>
<jaxb:typesafeEnumMember name="PLUS_X_PLUS_Y" value="+x+y"/>
<jaxb:typesafeEnumMember name="PLUS_X_MINUS_Y" value="+x-y"/>
<jaxb:typesafeEnumMember name="MINUS_X_PLUS_Y" value="-x+y"/>
<jaxb:typesafeEnumMember name="MINUS_X_MINUS_Y" value="-x-y"/>
</jaxb:typesafeEnumClass>
</jaxb:bindings>
</jaxb:bindings>
So you could do something like:
<jaxb:bindings schemaLocation="schema.xsd" node="/xs:schema">
<jaxb:bindings node="xs:simpleType[#name='CountyCodeEnumType']">
<jaxb:typesafeEnumClass>
<jaxb:typesafeEnumMember name="_1" value="01"/>
<jaxb:typesafeEnumMember name="_2" value="02"/>
<jaxb:typesafeEnumMember name="_3" value="03"/>
<jaxb:typesafeEnumMember name="_4" value="04"/>
</jaxb:typesafeEnumClass>
</jaxb:bindings>
</jaxb:bindings>
This would give you _4("04") which is quite close to what you originally wanted and does not conflict with Java syntax.
I'm using nodejs and node-soap as client to consume a webservice published on iis and developed in delphi. The webservice is published with document/literal style.
On Node I'm invoking and logging the response of the operations like this:
client[functionName](args, function (err, result) {
if (err) {
console.log(err);
} else {
console.log(result);
}
});
Here is a portion of the xml result from delphi:
...
<GetValuesResponse xmlns="urn:WS_TEST">
<res xmlns="urn:UTest">
<matrixData>
<TDoubleDynArray>
<double>4.32427893698308</double>
<double>4.40404718921869</double>
<double>4.50060875771443</double>
<double>4.56778202275494</double>
<double>4.61816197153533</double>
<double>4.73991351442126</double>
<double>4.78609513413661</double>
<double>4.8238800957219</double>
<double>4.8238800957219</double>
<double>4.81128510852681</double>
...
And this is the json obtained from node-soap (response):
...
"matrixData": {
"TDoubleDynArray": [
{
"double": [
"4.32427893698308",
"4.40404718921869",
"4.50060875771443",
"4.56778202275494",
"4.61816197153533",
"4.73991351442126",
"4.78609513413661",
"4.8238800957219",
"4.8238800957219",
"4.81128510852681",
...
I dont understand why node-soap includes the types of the data in the structure of the resulting json. Also, I don`t understand why arrays are parsed to json like an object with an array inside, instead of just an array.
Is there any way to ask node-soap just to include the data and the arrays just like simple arrays?
Here is the wsdl portion with the defines involved:
<element name="matrixData" type="ns6:TMatOfDouble"/>
<complexType name="TMatOfDouble">
<complexContent>
<restriction base="soapenc:Array">
<sequence/>
<attribute ref="soapenc:arrayType" n1:arrayType="ns1:TDoubleDynArray[]"/>
</restriction>
</complexContent>
</complexType>
<complexType name="TDoubleDynArray">
<complexContent>
<restriction base="soapenc:Array">
<sequence/>
<attribute ref="soapenc:arrayType" n1:arrayType="xs:double[]"/>
</restriction>
</complexContent>
</complexType>
Thanks in advance for any help
It result to be a bug in the node-soap library so we are trying to fix it.
I've created a webservice client with cxf with the xew plugin for list unwrapping
The problem is that the null in the list disappear.
E.g.:
I have an Request with a List<String> with Strings and a null-entry
When the request now arrives at the server it only contains the Strings not the null entry. So there are only 2 entries in the example list.
Here a example of the wsdl:
[..]
<!-- the request -->
<xsd:element name="createGroup">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="in0" nillable="true" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="1" name="in1" nillable="true" type="ns2:ArrayOfRole"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
[..]
<!-- the list which will be unwrapped -->
<xsd:complexType name="ArrayOfRole">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="Role" nillable="true" type="xsd:String"/>
</xsd:sequence>
</xsd:complexType>
I'm using maven to generate the ws client
<properties>
<cxf.version>3.0.5</cxf.version>
<jaxbBasic.version>0.6.5</jaxbBasic.version>
</properties>
[..]
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>src/main/java</sourceRoot>
<defaultOptions>
<bindingFiles>
<bindingFile>${basedir}/jaxbBindings.xml</bindingFile>
<bindingFile>${basedir}/jaxwsBindings.xml</bindingFile>
</bindingFiles>
<extraargs>
<!-- xew plugin for unwrapping list wrappers types NOTE: the args need to be over the others otherwise there are compilation errors -->
<extraarg>-xjc-Xxew</extraarg>
<extraarg>-xjc-Xxew:instantiate lazy</extraarg>
<!-- Generate toString, equals, hashcode methods -->
<extraarg>-xjc-Xts:style:de.company.tostring.CustomToStringStyle.DEFAULT</extraarg>
<extraarg>-xjc-Xequals</extraarg>
<extraarg>-xjc-XhashCode</extraarg>
</extraargs>
</defaultOptions>
<wsdlRoot>${ws.dirAbsolute}</wsdlRoot>
<includes>
<include>*.wsdl</include>
</includes>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.apache.cxf.xjcplugins</groupId>
<artifactId>cxf-xjc-ts</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>${jaxbBasic.version}</version>
</dependency>
<dependency>
<groupId>com.github.jaxb-xew-plugin</groupId>
<artifactId>jaxb-xew-plugin-fixed</artifactId> <!-- this is a custom version with a small modification see https://github.com/dmak/jaxb-xew-plugin/issues/44 -->
<version>1.7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-xjc</artifactId>
<version>2.2.11</version>
</dependency>
</dependencies>
</plugin>
jaxbBindings.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings version="2.1" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
<jaxb:globalBindings generateElementProperty="false"/>
</jaxb:bindings>
jaxwsBindings.xml
<jaxws:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
<jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle>
</jaxws:bindings>
A sample request:
final CreateGroup create = new CreateGroup();
create.setIn0("newgroup");
final List<String> roles = new ArrayList<String>();
roles.add("testrole");
roles.add(null);
roles.add("testrole2");
create.setIn1(roles);
final SamplePortType proxy = ..;
proxy.createGroup(create);
Is there a way that the null entry is still be present at the serverside?
The problem is that the jaxb-xew-plugin generates code that misses nillable = true
for the XmlElement of the List.
Generated by the plugin:
#XmlElementWrapper(required = true, nillable = true)
#XmlElement(name = "Role", namespace = "http://www.stackoverflow.com/example")
protected List<String> in1;
If you try, with added nillable=true, it will work:
#XmlElementWrapper(required = true, nillable = true)
#XmlElement(name = "Role", namespace = "http://www.stackoverflow.com/example", nillable = true)
protected List<String> in1;
So it seems the plugin is missing the nillable attribute for wrapped values.
I think the problem lies in this code part, where the XmlElement is "lifted" to an outer element and the nillable attribute is left out.
Adding the following code snippet to the mentioned code part will solve your problem and generate working code:
JExpression nillable = getAnnotationMemberExpression(xmlElementOriginalAnnotation, "nillable");
if (nillable != null) {
xmlElementAnnotation.param("nillable", nillable);
}
The problem discussed in this question is solved as of version 1.7 of the jaxb-xew-plugin. This issue keeps track of that case, here are the releases.
I'm not sure about this, but could it be that the generateElementProperty in the JAXB bindings may be causing the issue? According to the documentation, if that property is set to false, JAXB won't be able to roundtrip all XML documents. If set to true, you'll have to deal with JAXBElement class but, as the documentation says:
The JAXBElement type roundtrips the XML representation of name element across an unmarshal/marshal operation.
Check the examples in that page, it may help.
I am trying to fetch the namespace for an xml(xsd) file through Groovy.
The Node returned by the XmlParsers, and the GPathResult by XmlSlurper seems to ignore the namespace definitions.
As an example:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
trying to fetch the attributes of the rootNode through
rootNode.attributes()
will retrieve only:
targetNamespace:http://www.w3schools.com
elementFormDefault:qualified
and leave out the xml:ns and xmlns definitions. Same result is contained in the # attribute of GPathResult.
Seems this has nothing to do with the Node class implementation and relies on the XmlParsers used.
So how should the XmlParser be implemented to include these attributes in the node, and any reason this has been left outside of Groovy?
Use a different variant of XmlSlurper constructor:
def xml = """<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
</xs:schema>
"""
assert new XmlSlurper(false, false, false).parseText(xml).attributes() == [
'xmlns:xs':'http://www.w3.org/2001/XMLSchema',
'targetNamespace':'http://www.w3schools.com',
'xmlns':'http://www.w3schools.com',
'elementFormDefault':'qualified'
]