Converting Java generic object to XML using JAXB - java

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

Related

Java class to XSD

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.

WSImport bindings for two WSDLs with the same namespace

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?

Generate XSD File from an XML with xmltype in Oracle PL/SQL

My desired outcome is to get an XSD file generated from an XML straight in oracle
I'm using an SQL query in a PL/SQL procedure to generate an XMLType from a table.
With that XMLtype I then do a .GetClobVal() and return the clob version of that which I am currently copying into the following online tool
http://www.freeformatter.com/xsd-generator.html and then am able to generate an XSD out of this.
I know that this XSD is not perfect and will not be exactly how I want it, but it is pretty close.
I am wondering if anyone knows of a tool in Oracle that can do this, I can only find this for generating XSD from an Oracle type, but I don't use an Oracle Type in this situation, so please do not suggest using one.
Here is a sample of the code I use to create xml
With Accounts As ( Select XMLAgg(
XMLElement("AccountDetail",
XMLForest(1234 || Level As "UID",
'Test' || Level As "Name"))) As xmlData,
Count(*) as dataCount
From Dual
Connect By Level <= 2
)
Select XMLElement("GetAccountDataResponse",
XMLElement("ResponseInfo",
XMLElement("Code", 'Success'),
XMLElement("Message", 'Normal Successful Completion'),
XMLElement("DebugInfo",
XMLElement("DBVersion", 'V01.01.00'))),
Accounts.xmlData
).GetClobVal()
From Accounts;
Here is the XML sample:
<GetAccountDataResponse>
<ResponseInfo>
<Code>Success</Code>
<Message>Normal Successful Completion</Message>
<DebugInfo>
<DBVersion>V01.01.00</DBVersion>
</DebugInfo>
</ResponseInfo>
<AccountDetail>
<UID>12341</UID>
<Name>Test1</Name>
</AccountDetail>
<AccountDetail>
<UID>12342</UID>
<Name>Test2</Name>
</AccountDetail>
</GetAccountDataResponse>
When you copy the code into the xsd-generator that I mentioned earlier, you get the output of:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="GetAccountDataResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="ResponseInfo">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="Code"/>
<xs:element type="xs:string" name="Message"/>
<xs:element name="DebugInfo">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="DBVersion"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="AccountDetail" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:short" name="UID"/>
<xs:element type="xs:string" name="Name"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Which is pretty close and would allow me to do a replace on type="xs:short" to type="xs:int" within PL/SQL etc to get my desired outputs.
I would also be happy if there was a JAVA program that could do this, as Oracle has the support for running JAVA natively
There is no Oracle Tool that generate XSD from an XML.
You can try this Apache XMLBeans inst2xsd tool: http://xmlbeans.apache.org/docs/2.0.0/guide/tools.html#inst2xsd

How to parser XML schema and fetch the property names

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.

XSD FOR XML element multiple occurrences

i'm new to xsd and i want to generate xml like below with STUDENTRECORD occurring multiple times. i'm using jaxb to generate classes on the xsd
<STUDENTDETAIL>
<STUDENTINFORMATION>
<STUDENTRECORD>
<NAME>ABC</NAME>
<CLASS>4</CLASS>
<MAJOR>SCIENCE</MAJOR>
<GRADE>A</GRADE>
</STUDENTRECORD>
<STUDENTRECORD>
<NAME>DEF</NAME>
<CLASS>4</CLASS>
<MAJOR>SCIENCE</MAJOR>
<GRADE>B</GRADE>
</STUDENTRECORD>
</STUDENTINFORMATION>
My current xsd which generates STUDENTRECORD only once.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://webservice.com/WS" targetNamespace="http://webservice.com/WS" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Student" type="Student"/>
<xs:complexType name="Student">
<xs:sequence>
<xs:element name="STUDENTDETAIL">
<xs:complexType>
<xs:sequence>
<xs:element name="STUDENTINFORMATION">
<xs:complexType>
<xs:sequence>
<xs:element name="STUDENTRECORD">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="NAME"/>
<xs:element type="xs:string" name="CLASS"/>
<xs:element type="xs:string" name="MAJOR"/>
<xs:element type="xs:string" name="GRADE"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
Please help to fix.
Thanks
You just need to set a maxOccurs attribute on the STUDENTRECORD element declaration, like this:
<xs:element name="STUDENTRECORD" maxOccurs="unbounded">
This will allow the <STUDENTRECORD> to appear as many times you want. By default a given element is required to appear once.
Similarly, you can set minOccurs attribute to specify the minimal number of occurrences of an element.

Categories