I am writing a client that leverages two separate WSDLs from a third party. These two WSDLs have the exact same namespaces. So, I created binding files to put the objects generated from the two WSDLs into separate packages to avoid conflicts. However, there are a few common elements between these two WSDLs that share the exact same definition. Having these objects be generated into separate packages is not desirable since I'd like to share them. I have been unable to find any way to do this using binding files. The closest I got was to pull those shared elements out of the WSDLs and put them in a new XSD, change the targetNamespace of this XSD, and then target that namespace in the binding file to put it into a different package. The issue with this approach is that now the namespace of the generated common objects is different, so it doesn't serialize properly when calling the actual service.
The shared elements in question look like this:
<xs:complexType name="OperationResult">
<xs:sequence>
<xs:element name="MessageID" nillable="true" type="xs:string"/>
<xs:element name="Results" nillable="true" type="tns:ArrayOfCommandResult"/>
</xs:sequence>
</xs:complexType>
<xs:element name="OperationResult" nillable="true" type="tns:OperationResult"/>
<xs:complexType name="ArrayOfCommandResult">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="CommandResult" nillable="true" type="tns:CommandResult"/>
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfCommandResult" nillable="true" type="tns:ArrayOfCommandResult"/>
<xs:complexType name="CommandResult">
<xs:sequence>
<xs:element minOccurs="0" name="EntityID" type="xs:int"/>
<xs:element name="EntityType" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="ExchangeID" nillable="true" type="xs:string"/>
<xs:element name="Code" nillable="true" type="xs:string"/>
<xs:element name="Reason" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="Description" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="CommandResult" nillable="true" type="tns:CommandResult"/>
and they are just defined inside of the
<xs:schema elementFormDefault="qualified" targetNamespace="http://schemas.mypartnercompany.com/stuff/2013/06"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
Is there anything that I can do to get these common objects to generate to a separate package so I can share them between the two services, without having to change the namespace myself?
Related
Could someone please tell me what XSD matches this Java class?
public class MyClass {
private List<String> list1;
private List<String> list2;
private XMLGregorianCalendar date;
// getters and setters
}
I've tried the following, but I'm receiving an One of :attribute, :attributeGroup, :anyAttribute is expected error:
<xs:element name="myClass">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="list1" type="xs:string"/>
</xs:sequence>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="list2" type="xs:string"/>
</xs:sequence>
<xs:element name="date" nillable="true" type="xs:dateTime"/>
</xs:complexType>
</xs:element>
So it seems I'm not using the <xs:sequence> tag correctly. Could someone please shed some light? (I'm far from being an expert in XML-related stuff)...
I'm using Spring Boot 1.4.4.RELEASE version with Java 7.
The xs:sequence within a xs:complexType defines a specific order in which an elements children must occur. To create a list of elements you simply use the minOccurs and maxOccurs directly on the xs:element tag you want repeated, as follows:
<xs:element name="myClass">
<xs:complexType>
<xs:sequence>
<xs:element name="list1" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="list2" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="date" nillable="true" type="xs:dateTime"/>
</xs:sequence>
</xs:complexType>
</xs:element>
This should create the class you expect and require XML such as the following (order of tags matter):
<myClass>
<list1>a</list1>
<list1>b</list1>
<list2>y</list2>
<list2>z</list2>
<date>2019-06-26T00:00:00.0000000Z</date>
</myClass>
Placing minOccurs and maxOccurs on the xs:sequence tag requires the entire sequence of elements to be repeated.
I want to XML payloads like:
<ResponseDto>
<ResponseHeader>
<success>true</success>
</ResponseHeader>
<ResponseBody>
<ObjectA>
</ObjectA>
</ResponseBody>
</ResponseDto>
and another payload like:
<ResponseDto>
<ResponseHeader>
<success>true</success>
</ResponseHeader>
<ResponseBody>
<ObjectB>
</ObjectB>
</ResponseBody>
</ResponseDto>
so I want to make a class for ResponseDto which contains ResponseHeader Object and a generic Java Object in which I can place different types of objects, so I tried multiple types of Objects in a single class with #XMLElement(name = "ResponseBody") but it did not allow me to have same names of XMLElements
What can I do in this scenario?
Thanks in advance.
Most of enterprise applications use JAXB. You could get many tutorials some are below.
http://www.mkyong.com/java/jaxb-hello-world-example/
https://examples.javacodegeeks.com/core-java/xml/bind/jaxb-marshal-example/
https://www.javacodegeeks.com/2014/12/jaxb-tutorial-xml-binding.html
Step 1: First you would require to make xsd file. There are many online sites where xsd can be generated. Use http://xmlgrid.net/xml2xsd.html for now. XSD should look like this.
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ResponseDto">
<xs:complexType>
<xs:sequence>
<xs:element name="ResponseHeader">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="success"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ResponseBody">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="ObjectA" minOccurs="0"/>
<xs:element type="xs:string" name="ObjectB" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Refer my below post for reference.
read and get xml values in java
I want to parse XML schema and then fetch elements from schema in that if there is complex object then that attributes should be fetch with prefix as main complex type.
for instance
<xs:element name="address" >
<xs:complexType>
<xs:sequence>
<xs:element name="city" type="xs:string"/>
<xs:element name="street" type="xs:string"/>
<xs:element name="zipcode" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Address is complex type if we want to fetch zipcode then it should be like 'address.zipcode'
Is there a way to do this or we have to check manually for type and create fields.
below is XML schema.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Employee">
<xs:complexType>
<xs:sequence>
<xs:element name="empId" type="xs:integer"/>
<xs:element name="firstName" type="xs:string"/>
<xs:element name="lastName" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="address" >
<xs:complexType>
<xs:sequence>
<xs:element name="city" type="xs:string"/>
<xs:element name="street" type="xs:string"/>
<xs:element name="zipcode" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
Extracting information from raw schema documents is challenging unless you know that the schema will be restricted to use a subset of the language: for example, that it will not use named model groups, or substitution groups, or complex types derived by extension.
It's easy to write something (e.g. in XSLT) that works with your examples - or at least, it would be easy if we had a clearer picture of what output you wanted - but writing something that can handle ANY schema is much more difficult.
It may be better to work with the compiled representation of a schema produced by a "real" schema processor. For example Xerces has an API allowing access to the "schema components" produced by the schema compiler, and Saxon has an option to produce an SCM file (schema component model) which is an XML file containing the same information; at this level you don't have to cope with all the variety of ways the source schema might have been written.
I have a xsd where there are 2 complextype elements under <Customer> complextype. One is <NormalCustomer> and <PrivilegedCustomer>. In my xml, I want either Normal or Privileged customer to be present under <Customer> tag based on the id attribute of Normal/Privileged customers.
below is my xsd
<xs:choice>
<xs:element name="normalCustomer" type="tns:normalCustomer" minOccurs="0" nillable="true"/>
<xs:element name="privilegedcustomer" type="tns:privilegedcustomer" minOccurs="0" nillable="true"/>
</xs:choice>
Complextype NormalCustomer
<xs:complexType name="normalCustomer">
<xs:sequence>
<xs:element name="id" type="xs:long"/>
<xs:element name="customerName" type="xs:string" minOccurs="1"/>
<xs:element name="customerType" type="xs:string" minOccurs="1"/>
</xs:sequence>
</xs:complexType>
Complextype PrivilegedCustomer
<xs:complexType name="privilegedCustomer">
<xs:sequence>
<xs:element name="id" type="xs:long"/>
<xs:element name="customerName" type="xs:string" minOccurs="1"/>
<xs:element name="customerType" type="xs:string" minOccurs="1"/>
</xs:sequence>
</xs:complexType>
Note: Am using JAXB for processing
Please suggest me how can I modify the tag to achieve my requirement.
Remove minOccurs="0" nillable="true" from both elements. The <xs:choice> enforces that exactly one of the elements are present. If none present are allowed, add minOccurs="0" to <xs:choice>.
I'm doing Java-first development on a service and the WSDL file being generated (I'm using Tomcat v6.0 as my container with the CXF Servlet) is using arg0, arg1 etc. as the parameter names for my service methods rather than using the actual parameter name specified in my Java code. Is this a known shortcoming or am I doing something wrong? The WSDL isn't very self-documenting with parameter names like this!
Here's an example wsdl snippet:
<xs:complexType name="insertVendor">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string"/>
<xs:element minOccurs="0" name="arg1" type="xs:string"/>
<xs:element minOccurs="0" name="arg2" type="xs:string"/>
<xs:element minOccurs="0" name="arg3" type="xs:string"/>
<xs:element minOccurs="0" name="arg4" type="xs:string"/>
<xs:element minOccurs="0" name="arg5" type="xs:string"/>
<xs:element minOccurs="0" name="arg6" type="xs:string"/>
<xs:element minOccurs="0" name="arg7" type="xs:string"/>
<xs:element minOccurs="0" name="arg8" type="xs:string"/>
<xs:element minOccurs="0" name="arg9" type="xs:string"/>
<xs:element minOccurs="0" name="arg10" type="xs:string"/>
<xs:element minOccurs="0" name="arg11" type="xs:string"/>
</xs:sequence>
Thanks,
mallesh
You can create request class and pass it in service method
Class Requestclass(){
// all the arguments you want, create POJO class
}
pass this class in your method,
insertVendor(RequestClass req){}
Here is the answer
Official answer: The JAX-WS spec (specifically section 3.6.1) mandates that it be generated this way. To customize the name, you have to use an #WebParam(name = "blah") annotation to specify better names. (You can use #WebResult for the return value, but you'll only see the results if you look at the XML.)