Create a nested element with blank namespace in a schema definition - java

I have a remote system that returns an XML similar to the one below.
<BalanceResponse xmlns="http://example.com/balance">
<BalanceResult>
<Balance xmlns="">
<amount>10</amount>
<Balance>
</BalanceResult>
</BalanceResponse>
I created an xsd to match it
<s:schema elementFormDefault="qualified" targetNamespace="http://example.com/balance">
<s:element name="BalanceResponse">
<s:complexType>
<s:element minOccurs="0" maxOccurs="1" name="BalanceResult">
<s:complexType>
<s:element minOccurs="0" maxOccurs="1" name="Balance">
<s:complexType>
<s:element minOccurs="0" maxOccurs="1" name="amount" type="s:decimal" />
</s:complexType>
</s:element>
</s:complexType>
</s:element>
</s:complexType>
</s:schema>
I use JAXB to generate the stub classes. However, I know that my (un/)marshaller cannot bind the Balance element because the namespace is different.
Question is, how can i declare a different (blank)namespace for my element Balance?

You could do something like the following. Since elementFormDefault is unqualified all global elements (BalanceResponse and BalanceResult will be namespace qualified and all local elements (Balance and amount) won't be.
<?xml version="1.0" encoding="UTF-8"?>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/balance"
xmlns:tns="http://example.com/balance"
elementFormDefault="unqualified">
<element name="BalanceResponse">
<complexType>
<sequence>
<element ref="tns:BalanceResult"/>
</sequence>
</complexType>
</element>
<element name="BalanceResult">
<complexType>
<sequence>
<element name="Balance">
<complexType>
<sequence>
<element name="amount" type="int"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
If as in the XML Schema in your question put elementFormDefault as qualified then it would expect all of the XML elements to be namespace qualified.

Related

How 'minOccurs' and 'maxOccurs' attribute value will generated inside the `element` tag of the WSDL file?

We have custom java code that deployed in the JBoss. We are firing the webservice call and the WSDL file is generating by using the Apache Axis framework.
My question is for some of the tag, minOccurs and maxOccurs attribute is present, but for some other tag, those attributes are not present.
If I want minOccurs and maxOccurs attribute inside the element tag, then where I have to configure? How this Apache Axis framework will generate these attribute.
Sample WSDL :
<wsdl:definitions xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="urn:sif.siperian.com" xmlns:intf="urn:sif.siperian.com"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:sif.siperian.com">
<!--
WSDL created by Apache Axis version: 1.3
Built on Oct 05, 2005 (05:23:37 EDT)
-->
<wsdl:types>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" targetNamespace="urn:sif.siperian.com">
<complexType name="Account">
<sequence>
<element name="accountNumber" nillable="true" type="xsd:string"/>
<element name="accountType" nillable="true" type="xsd:string"/>
<element name="cardholderName" nillable="true" type="xsd:string"/>
<element name="city" nillable="true" type="xsd:string"/>
<element name="expirationMonth" nillable="true" type="xsd:string"/>
<element name="expirationYear" nillable="true" type="xsd:string"/>
<element name="hubStateInd" nillable="true" type="xsd:string"/>
<element name="issuingCompany" nillable="true" type="xsd:string"/>
<element name="pkeySrcObject" nillable="true" type="xsd:string"/>
<element name="postalCode" nillable="true" type="xsd:string"/>
<element name="rowidObject" nillable="true" type="xsd:string"/>
<element name="securityCode" nillable="true" type="xsd:string"/>
<element name="source" nillable="true" type="xsd:string"/>
<element name="stateProvince" nillable="true" type="xsd:string"/>
<element name="streetName" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
<complexType name="ArrayOfAccount">
<sequence>
<element maxOccurs="unbounded" minOccurs="0" name="item"
type="impl:Account"/>
</sequence>
</complexType>
</schema>
</wsdl:types>
</wsdl:definitions>
In the above WSDL, the <complexType name="Account"> is not having property minOccurs and maxOccurs.
Where as, the <complexType name="ArrayOfAccount"> is having both the properties.
The following is a Java Code sample on how to build the following element:
<element maxOccurs="1" minOccurs="0" name="Test" nillable="true" type="xsd:string"/>
Java Code:
elemField = new org.apache.axis.description.ElementDesc();
elemField.setFieldName("test");
elemField.setXmlName(new javax.xml.namespace.QName("http://www.test.com", "Test"));
elemField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
elemField.setMinOccurs(0);
elemField.setNillable(true);
Hope this helps.

recursive xsd generates java class with Objects instead of the given Type

So, I have an object which can contain a list of Objects of that type. I wrote an XSD which looks something like this:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="myNamespace" elementFormDefault="qualified">
<complexType name="BinModel">
<sequence>
<element type="string" name="min" />
<element type="string" name="max" />
<element type="string" name="fieldname" />
<element type="int" name="defaultValue" />
<element xmlns:ref="BinModel" name="innerBins" maxOccurs="unbounded" minOccurs="0" />
</sequence>
</complexType>
<element name="AllBins">
<complexType>
<sequence>
<element type="string" name="fieldnames" maxOccurs="unbounded" minOccurs="0"/>
<element type="int" name="defaultValue"/>
<element xmlns:type="BinModel" name="outerBins" maxOccurs="unbounded" minOccurs="0" />
</sequence>
</complexType>
</element>
</schema>
It produces two java classes, BinModel and AllBins respectively, but in each of those classes, even though I specify that they contain a list of type BinModel, it produces a List of type Object.
How do I generate a class which has a List of BinModels?
So I realized something was wrong when it took me adding xmlns before type and ref in order to not show errors in the editor. I looked at another xsd for a recursively defined Object somewhere else in my stupidly huge codebase to try and find a solution and discovered two things.
1. We were defining our own namespace
2. We referenced our own objects within that namespace.
So the corrected code looks something like this:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:myProject="projectNamespace" targetNamespace="myNamespace" elementFormDefault="qualified">
<complexType name="BinModel">
<sequence>
<element type="string" name="min" />
<element type="string" name="max" />
<element type="string" name="fieldname" />
<element type="int" name="defaultValue" />
<element type="myProject:BinModel" name="innerBins" maxOccurs="unbounded" minOccurs="0" />
</sequence>
</complexType>
<element name="AllBins">
<complexType>
<sequence>
<element type="string" name="fieldnames" maxOccurs="unbounded" minOccurs="0"/>
<element type="int" name="defaultValue"/>
<element type="myProject:BinModel" name="outerBins" maxOccurs="unbounded" minOccurs="0" />
</sequence>
</complexType>
</element>
</schema>

Why spring wrong generate java classes from xsd

I have xsd schema below describe the
<xs:element name="ReqStartTest">
<xs:complexType>
<xs:sequence>
<xs:element name="Version" >
<xs:simpleType>
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:element>
<xs:element name="Time" >
<xs:simpleType>
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:element>
<xs:element ref="tns:StartTestRequest" minOccurs="1" maxOccurs="1"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="StartTestRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" >
<xs:simpleType>
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
After i generate java classes from xsd file, and recieve *.wsdl file. After i testing *.wsdl file in SOAPUI, I see just "StartTestRequest" request. My question, why/where my input data ("Version","Time") in request?
Thanks in advance.
Spring only generates request/response for the elements that has the postfixes "request" and "response". In this case, you are referencing "StartTestRequest" from "ReqStartTest". So, you will only see "StartTestRequest" which only has the name field in it. You should extend or reference "ReqStartTest" in your "StartTestRequest"
Following should work fine.
<complexType name="ReqStartTest">
<sequence>
<element name="Version" type="string"/>
<element name="Time" type="string"/>
</sequence>
</complexType>
<element name="StartTestRequest">
<complexType>
<complexContent>
<extension base="tns:ReqStartTest">
<sequence>
<element name="Name" type="string"/>
</sequence>
</extension>
</complexContent>
</complexType>
</element>
Update:
Spring requires predefined suffixes to identify elements that are requests or responses of a web service. Default suffixes are "Request" and "Response". You can change it in the configuration. This thread might help you: Spring-ws: How to create Wsdl from an xsd with no "Request" element
Also this is the closest you will get without changing suffixes:
<element name="ReqStartTestRequest">
<complexType>
<sequence>
<element name="version" type="string"/>
<element name="time" type="string"/>
<element name="startTestRequest" type="tns:StartTestRequest"/>
</sequence>
</complexType>
</element>
<complexType name="StartTestRequest">
<sequence>
<element name="name" type="string"/>
</sequence>
</complexType>
I highly advise you to follow naming conventions. For example, first letter of a variable or non constant field should be lower case (camelcase notation).

xml schema validation error “The content of element 'flowPara' is not complete”

I need to valid XSD for a XML file.
This is xml file.
<?xml version="1.0" encoding="UTF-8"?>
<edge xmlns="http://www.example.org/flow">
<flowPara
style="letter-spacing:0px;fill:#000000;
font-size:9pt;font-family:Arial;text-anchor:start;text-align:start;"
id="textArea_38">
Text Flow checking and
<flowSpan style="fill:#FA0101; ">
font color change
text
<flowSpan style="fill:#C5A2A2; " />
</flowSpan>
in
<flowSpan
style="font-style:italic;letter-spacing:0px;fill:#000000;
font-size:9pt;font-family:Arial;text-anchor:start;text-align:start;">text
area
</flowSpan>
.
<flowSpan style="letter-spacing:0px;">
<flowSpan
style="text-decoration:underline;letter-spacing:0px;fill:#000000;
font-size:9pt;font-family:Arial;text-anchor:start;text-align:start;">Text
Flow
</flowSpan>
checking and
<flowSpan style="fill:#FA0101; ">
font color
change text
<flowSpan style="fill:#C5A2A2; ">
<flowSpan style="fill:#000000;
">in text area.</flowSpan>
</flowSpan>
</flowSpan>
</flowSpan>
</flowPara>
</edge>
This is XSD file which i created .
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/flow"
xmlns:tns="http://www.example.org/flow" elementFormDefault="qualified">
<element name="edge">
<complexType>
<sequence>
<element name="flowPara" maxOccurs="unbounded">
<complexType mixed="true">
<sequence>
<element name="flowspan" maxOccurs="unbounded">
<complexType mixed="true">
<sequence>
<element name="flowspan" maxOccurs="unbounded">
<complexType mixed="true">
<simpleContent>
<extension base="string">
<attribute name="style" type="string" />
</extension>
</simpleContent>
</complexType>
</element>
</sequence>
<attribute name="style" type="string" />
</complexType>
</element>
</sequence>
<attribute name="style" type="string" />
<attribute name="id" type="string" />
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
i faced this kind of exception
Exception: cvc-complex-type.2.4.b: The content of element 'flowPara' is not complete. One of '{"http://www.example.org/flow":flowspan}' is expected.
1) In your schema, you have flowspan with the s in lowercase in several places. Change that to flowSpan.
2) You declared mixed content, but your flowSpan element is not optional, so it will always be required and will not validate it if the contents of flowSpan don't contain another flowSpan. Add minOccurs="0" so it becomes optional.
3) You don't need to declare simple content if you have mixed content with an optional nested flowSpan. Your schema could be reorganized using a reference for flowSpan, since it's used recursively. You could try this:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/flow"
xmlns:tns="http://www.example.org/flow"
elementFormDefault="qualified">
<element name="edge">
<complexType>
<sequence>
<element name="flowPara" maxOccurs="unbounded">
<complexType mixed="true">
<sequence>
<element ref="tns:flowSpan" maxOccurs="unbounded"/>
</sequence>
<attribute name="style" type="string" />
<attribute name="id" type="string" />
</complexType>
</element>
</sequence>
</complexType>
</element>
<element name="flowSpan">
<complexType mixed="true">
<sequence>
<element ref="tns:flowSpan" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="style" type="string" />
</complexType>
</element>
</schema>
You didn't say minOccurs='0', so it requires one.

how to Convert org.apache.xmlbeans.XmlObject to my customJavaObject

I am having a method where I am receiving XmlObject as an argument in the method and now I want to convert it into the java corresponding java object , that I have to pass in other webservice.
I have tried all the possible ways but not able to get it.
Code :
public static boolean updateAddress_V2(XmlObject xmlObject) throws XmlException{
AlarsDataService dataService=new AlarsDataService();
CustomerV2 customerV2=CustomerV2.Factory.parse(xmlObject.toString());
com.alars.osb.java.customer.CustomerV2.Customer customerXML=customerV2.getCustomer();
}
but when I am checking customerXML is coming as null.
Here is the XMLObject string value :
<Customer_V2 xmlns="http://www.alars.com/osb/java/Customer">
<Customer>
<customerId>4</customerId>
<driverLicense>XBRT245</driverLicense>
<firstName>ALEX</firstName>
<lastName>CINTRA</lastName>
<dob>21-11-1986</dob>
<addressLine1>10 Florence St</addressLine1>
<city>BOSTON</city>
<zipCode>02148</zipCode>
</Customer>
</Customer_V2>
Customer XSD :
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.alars.com/osb/java/Customer"
xmlns:tns="http://www.alars.com/osb/java/Citation" elementFormDefault="qualified">
<complexType name="Customer">
<sequence>
<element name="customerId" type="long"></element>
<element name="driverLicense" type="string"></element>
<element name="firstName" type="string"></element>
<element name="lastName" type="string"></element>
<element name="dob" type="date"></element>
<element name="addressLine1" type="string"></element>
<element name="city" type="string"></element>
<element name="zipCode" type="string"></element>
</sequence>
</complexType>
<complexType name="Customer_V2">
<sequence>
<element name="Customer">
<complexType>
<sequence>
<element name="customerId" type="long"></element>
<element name="driverLicense" type="string"></element>
<element name="firstName" type="string"></element>
<element name="lastName" type="string"></element>
<element name="dob" type="date"></element>
<element name="addressLine1" type="string"></element>
<element name="city" type="string"></element>
<element name="zipCode" type="string"></element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</schema>
Any advise folks.. how to achieve this ??
You change the schema type of XmlObject to required CustomerV2 as follows since we do not know the type ahead.
CustomerV2 customerV2 = (CustomerV2)
xmlObject.changeType(CustomerV2.type);
To check the schema type against the required CustomerV2 schema type, you can do the following.
xmlObject.schemaType().isAssignableFrom(CustomerV2 .type);
The XML does not match to the XSD. Especially, the XSD is missing the top element entries. Use following Schema instead and re-generate your XMLBeans classes:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.alars.com/osb/java/Customer" xmlns:customer="http://www.alars.com/osb/java/Customer">
<xs:element name="CustomerParent">
<xs:complexType>
<xs:sequence>
<xs:element ref="customer:Customer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Customer">
<xs:complexType>
<xs:sequence>
<xs:element ref="customer:customerId"/>
<xs:element ref="customer:driverLicense"/>
<xs:element ref="customer:firstName"/>
<xs:element ref="customer:lastName"/>
<xs:element ref="customer:dob"/>
<xs:element ref="customer:addressLine1"/>
<xs:element ref="customer:city"/>
<xs:element ref="customer:zipCode"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="customerId" type="xs:integer"/>
<xs:element name="driverLicense" type="xs:NCName"/>
<xs:element name="firstName" type="xs:NCName"/>
<xs:element name="lastName" type="xs:NCName"/>
<xs:element name="dob" type="xs:NMTOKEN"/>
<xs:element name="addressLine1" type="xs:string"/>
<xs:element name="city" type="xs:NCName"/>
<xs:element name="zipCode" type="xs:integer"/>
</xs:schema>
Parse your XML as follows:
final CustomerParentDocument customerParentV1 = CustomerParentDocument.Factory.parse(file);

Categories