How to parser XML schema and fetch the property names - 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.

Related

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

Converting Java generic object to XML using JAXB

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

Compiling XML schema to Java with key/keyref identity constraints

Lets say I have the following XML schema:
<xs:schema
xmlns="http://www.example.com/data"
xmlns:data="http://www.example.com/data"
targetNamespace="http://www.example.com/data"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="data">
<xs:complexType>
<xs:all>
<xs:element name="countries">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="country" type="country"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="types">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="type" type="type"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="products">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="product" type="product"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
<xs:key name="countryNameKey">
<xs:selector xpath=".//data:country"/>
<xs:field xpath="#name"/>
</xs:key>
<xs:key name="typeNameKey">
<xs:selector xpath=".//data:type"/>
<xs:field xpath="#name"/>
</xs:key>
<xs:keyref name="countryNameRef" refer="data:countryNameKey">
<xs:selector xpath=".//data:product"/>
<xs:field xpath="#country"/>
</xs:keyref>
<xs:keyref name="typeNameRef" refer="data:typeNameKey">
<xs:selector xpath=".//data:product"/>
<xs:field xpath="#type"/>
</xs:keyref>
<xs:unique name="uniqueProducts">
<xs:selector xpath=".//data:product"/>
<xs:field xpath="#country"/>
<xs:field xpath="#type"/>
</xs:unique>
</xs:element>
<xs:complexType name="country">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="type">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="product">
<xs:attribute name="country" type="xs:string" use="required"/>
<xs:attribute name="type" type="xs:string" use="required"/>
</xs:complexType>
</xs:schema>
Excuse the contrived example.
As you can see it is tabular data. I define some countries, then I define some types of product. I then define individual products as a type from a country, cheese from France for example.
The important thing to note here is that I use key and keyref to cross-reference all products back to the original country/type.
So, my question is:
Is it possible to compile this schema into java classes that can be unmarshalled using Eclipse Moxy with the cross-references intact?
I know that the JAXB 2.0 spec does not support key/keyref. I also know that Moxy Does.1
Further I know that Moxy doesn't have a Maven plugin and, in any case, uses XJC generated classes and simply adds in a jaxb.properties file to specify the JAXB provider to use.2
So I suspect the answer to my question is "no, you have to craft the classes yourself", but I thought I'd check before I abandoned hope.
To clarify, My product element currently compiles (using maven-jaxb2-plugin) to
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "product")
public class Product implements Cloneable, CopyTo, Equals, HashCode, ToString {
#XmlAttribute(name = "country", required = true)
protected String country;
#XmlAttribute(name = "type", required = true)
protected String type;
//getters and setters
}
It, references the Strings rather than the Country and Type objects.
Currently EclipseLink JAXB (MOXy) only extends the XJC tool to add a jaxb.properties file that indicates that MOXy is the JAXB (JSR-222) provider. I have entered the following enhancement (currently unscheduled) to track this request:
http://bugs.eclipse.org/411619

How to properly declare an extension within a schema?

In my schema file below, I have an element Stat which extends Entity. As far as I am aware, I follow w3's example, but when I go to parse the schema (and the xml that uses the schema) with through java's DocumentBuilderFactory and SchemaFactory I get this exception:
org.xml.sax.SAXParseException; systemId: file:/schema/characterschema.xsd;
src-resolve.4.2: Error resolving component 'cg:Entity'. It was detected that
'cg:Entity' is in namespace 'http://www.schemas.theliraeffect.com/chargen/entity',
but components from this namespace are not referenceable from schema document
'file:/home/andrew/QuasiWorkspace/CharacterGenerator/./schema/characterschema.xsd'.
If this is the incorrect namespace, perhaps the prefix of 'cg:Entity' needs
to be changed. If this is the correct namespace, then an appropriate 'import'
tag should be added to '/schema/characterschema.xsd'.
So, it seems that I cannot see my namespace within my schema. Do I need to import my schema into itself or am I completely misreading this exception? Could it be that I am declaring my schema incorrectly?
This is my schema for reference:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:cg="http://www.schemas.theliraeffect.com/chargen/entity"
elementFormDefault="qualified">
<xs:element name="Entity">
<xs:complexType>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="description" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="Stat">
<xs:complexType>
<xs:complexContent>
<xs:extension base="cg:Entity">
<xs:sequence>
<xs:element name="table" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:schema>
There are two problems with your schema. First, you don't declare a targetNamespace so the Entity and Stat elements you are defining are not in a namespace. Second, a type can't extend an element, only another type.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:cg="http://www.schemas.theliraeffect.com/chargen/entity"
targetNamespace="http://www.schemas.theliraeffect.com/chargen/entity"
elementFormDefault="qualified">
<xs:complexType name="EntityType">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="description" type="xs:string"/>
</xs:complexType>
<xs:element name="Entity" type="cg:EntityType" />
<xs:complexType name="StatType">
<xs:complexContent>
<xs:extension base="cg:EntityType">
<xs:sequence>
<xs:element name="table" type="xs:string" minOccurs="0"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="Stat" type="cg:StatType" />
</xs:schema>
Here I'm defining two types, one of which extends the other, and two top level elements of the respective types. All the top-level types and elements are defined into the targetNamespace of the schema, and the nested table element inside StatType is also in this namespace because of the elementFormDefault="qualified" - without this the Entity and Stat elements would be in the http://www.schemas.theliraeffect.com/chargen/entity namespace but the table element would be in no namespace.

Categories