XML to Java and vice versa using xsd schema - java

Below is my Schema.xsd
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:ns1="http://www.example.org/address" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://www.example.org/address" schemaLocation="www.example.org_address.xsd"/>
<xs:element name="dependant" type="dependant"/>
<xs:element name="employee" type="employee"/>
<xs:complexType name="employee">
<xs:sequence>
<xs:element name="dependantVO" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element ref="dependant" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="address" type="ns1:address" minOccurs="0"/>
<xs:element name="dob" type="xs:dateTime" minOccurs="0"/>
<xs:element name="joiningBonus" type="xs:decimal" minOccurs="0"/>
<xs:element name="name" type="xs:string" minOccurs="0"/>
<xs:element name="permanent" type="xs:boolean"/>
<xs:element name="role" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="id" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="dependant">
<xs:sequence>
<xs:element name="name" type="xs:string" minOccurs="0"/>
<xs:element name="relation" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Below is my address.xsd
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" targetNamespace="http://www.example.org/address" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="address">
<xs:sequence>
<xs:element name="addressLine1" type="xs:string" minOccurs="0"/>
<xs:element name="addressLine2" type="xs:string" minOccurs="0"/>
<xs:element name="city" type="xs:string" minOccurs="0"/>
<xs:element name="zip" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Now if i marshal the object "Employee" below is the generated employee.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee id="12">
<dependantVO>
<dependant>
<name>Vin Diesel</name>
<relation>Friend</relation>
</dependant>
<dependant>
<name>Black Ryan</name>
<relation>GF</relation>
</dependant>
</dependantVO>
<address>
<addressLine1>My Company</addressLine1>
<addressLine2>bangalore east</addressLine2>
<city>Bangalore</city>
<zip>560549</zip>
</address>
<dob>2015-07-28T10:04:34.599+05:30</dob>
<joiningBonus>10234.35467000000062398612499237060546875</joiningBonus>
<name>Paul Walker</name>
<permanent>true</permanent>
<role>SE</role>
</employee>
I have a problem of ordering the xml tags. Eg: Suppose i want addressline1 to be generated inside "employee" tag and outside "address" tag, also dependant name to be generated inside "employee" tag and outside "dependantVO" and "dependant" tag. Below is the xml that should be generated after the schema change
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee id="12">
<addressLine1>My Company</addressLine1>
<city>Bangalore</city>
<dependantVO>
<dependant>
<name>Vin Diesel</name>
<relation>Friend</relation>
</dependant>
<dependant>
<name>Black Ryan</name>
<relation>GF</relation>
</dependant>
</dependantVO>
<address>
<addressLine2>bangalore east</addressLine2>
<zip>560549</zip>
</address>
<dob>2015-07-28T10:04:34.599+05:30</dob>
<joiningBonus>10234.35467000000062398612499237060546875</joiningBonus>
<name>Paul Walker</name>
<permanent>true</permanent>
<role>SE</role>
</employee>
Note the addressLine1 tag and city tag is out of address tag and created inside employee tag. This is required because some of the common information are to be accessed easy from the generated xml. If someone tried this case or already done it, please help me out...

Related

Prefix not appeared n on generated XML

I've this XSD Schema definition
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns2="http://www.xxxx.xxxxxxxxx.xxxxxxxx/xxxx/xxxx">
<xs:element name="myRootElemnt">
<xs:complexType>
<xs:sequence>
<xs:element name="messageType">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:short" name="id" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element type="xs:int" name="time" />
<xs:element type="xs:short" name="date" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
The generated XML is:
But, the XML still incomplete, it must contains xmlns:ns2="http://www.xxxx.xxxxxxxxx.xxxxxxxx/xxxx/xxxx"> and the prefix ns2 for the root element , like this:
Any Solutions?

s4s-att-invalid-value: Invalid attribute value for 'name' in element 'element'

XML
<ns2:Response xmlns:ns2="http://test.com/" Id="122212">
<Infos size="1">
<Info>
<name>test</name>
</Info>
</Infos>
</ns2:Response>
Generated XSD
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- XML Schema Generated from XML Document on Mon Feb 20 2017 23:20:03 GMT+0530 (India Standard Time) -->
<!-- with XmlGrid.net Free Online Service http://xmlgrid.net -->
<xs:element name="ns2:Response">
<xs:complexType>
<xs:sequence>
<xs:element name="Infos">
<xs:complexType>
<xs:sequence>
<xs:element name="Info">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="xmlns:ns2" type="xs:string"></xs:attribute>
<xs:attribute name="Id" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
Error
SAX Exception: s4s-att-invalid-value: Invalid attribute value for
'name' in element 'element'. Recorded reason:
cvc-datatype-valid.1.2.1: 'ns2:Response' is not a valid value for
'NCName'.
There are several changes required for your XML and XSD, including:
Change <xs:element name="ns2:Response"> to <xs:element
name="Response"> because element name declarations must be
non-colonized names (NCNAMEs).
Delete <xs:attribute name="xmlns:ns2".../> because namespaces
cannot be declared as attributes.
Add a targetNamespace to the XSD that matches the namespace of the root element in the XML document.
Import a separate XSD for those elements that you wish to be in no namespace (given that your root elements is in a namespace). You must use a separate XSD to accomplish this.
Altogether, your XML,
<?xml version="1.0" encoding="UTF-8"?>
<ns2:Response xmlns:ns2="http://test.com/"
Id="122212">
<Infos size="1">
<Info>
<name>test</name>
</Info>
</Infos>
</ns2:Response>
will validate successfully against these XSD:
Main
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
xmlns:ns="http://test.com/"
targetNamespace="http://test.com/">
<xs:import schemaLocation="Infos.xsd"/>
<xs:element name="Response">
<xs:complexType>
<xs:sequence>
<xs:element ref="Infos"/>
</xs:sequence>
<xs:attribute name="Id" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
Imported (Infos.xsd)
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Infos">
<xs:complexType>
<xs:sequence>
<xs:element name="Info">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
I was able to get a parsed file by, as the above answer suggests, adding a target namepsace to the schema and by adding the ns prefix to all elements.
<?xml version="1.0" encoding="UTF-8"?>
<ns2:Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://test.com testq1.xsd" xmlns:ns2="http://test.com" Id="122212">
<ns2:Infos size="1">
<ns2:Info>
<ns2:name>test</ns2:name>
</ns2:Info>
</ns2:Infos>
and the schema:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://test.com"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="Response">
<xs:complexType>
<xs:sequence>
<xs:element name="Infos">
<xs:complexType>
<xs:sequence>
<xs:element name="Info">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Id" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
You can approach this in 2 ways.
Approach 1 - multiple schemas
The more typical approach is to have a schema one for each namespace used.
So you end up with schemas that look like this
SampleXml0.xsd
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2017 (https://www.liquid-technologies.com) -->
<xs:schema xmlns:ns2="http://test.com/" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://test.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation="C:\Temp\StackOverflow\42351409\SampleXml1.xsd" />
<xs:element name="Response">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="Infos" />
</xs:sequence>
<xs:attribute name="Id" type="xs:unsignedInt" use="optional" />
</xs:complexType>
</xs:element>
</xs:schema>
SampleXml1.xsd
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2017 (https://www.liquid-technologies.com) -->
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Infos">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="Info">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="name" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:unsignedByte" use="optional" />
</xs:complexType>
</xs:element>
</xs:schema>
Approach 2 - changing elementFormDefault
Now this is quite specific to your example, but as its only the root element that is qualified with a namespace its possible to change elementFormDefault to unqualified. This has the effect of forcing the elements defined as root element in the schema to have a namespace qualification, while the other elements do not.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2017 (https://www.liquid-technologies.com)-->
<xs:schema xmlns:ns2="http://test.com/" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://test.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Response">
<xs:complexType>
<xs:sequence>
<xs:element name="Infos" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="Info" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:unsignedByte" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Id" type="xs:unsignedInt" use="optional" />
</xs:complexType>
</xs:element>
</xs:schema>
I would probably recommend creating multiple schemas as elementformdefault is typically overlooked by client implementations and ignored.
Why three <xs:sequence> elements? do you really need that? Could you explain better how your code is organized? Usually it is pretty simple, like this:
<xsd:element name="ns2:Response">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xs:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>

xml validation failed with attribute required and attribute not allowed error, which is ambiguous

I have defined following schema for XML
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.learnjava.com"
xmlns="http://www.learnjava.com"
elementFormDefault="qualified"
attributeFormDefault="qualified">
<!-- simple elements -->
<xs:element name="name" type="xs:string"/>
<xs:element name="hod" type="xs:string"/>
<xs:element name="dept" type="xs:integer"/>
<!-- attributes -->
<xs:attribute name="id" type="xs:integer"/>
<!-- complex elements -->
<xs:element name="department">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="hod" minOccurs="0"/>
</xs:sequence>
<xs:attribute ref="id" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="departments">
<xs:complexType>
<xs:sequence>
<xs:element ref="department" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="student">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="dept"/>
</xs:sequence>
<xs:attribute ref="id" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="students">
<xs:complexType>
<xs:sequence>
<xs:element ref="student" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="school">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="departments"/>
<xs:element ref="students"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
As per the schema, the attribute id is required for <department> and <student> tags and I have below XML which adheres to this rule
<?xml version="1.0" encoding="UTF-8"?>
<school xmlns="http://www.learnjava.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.learnjava.com ex2.xsd">
<name>TAMUC</name>
<departments>
<department id="1001">
<name>Computer Science</name>
</department>
<department id="1002">
<name>Social Science</name>
<hod>Jeff</hod>
</department>
</departments>
<students>
<student id="5001">
<name>Frank</name>
<dept>1001</dept>
</student>
<student id="5002">
<name>Paul</name>
<dept>1001</dept>
</student>
</students>
</school>
But the validation fails with below error
Error - Line 7, 25: org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 25; cvc-complex-type.3.2.2: Attribute 'id' is not allowed to appear in element 'department'.
Error - Line 7, 25: org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 25; cvc-complex-type.4: Attribute 'id' must appear on element 'department'.
[..further errors omited...]
Not sure for what is wrong. Both the error messages are contradictory
The validation fails if I remove "id" attributes from and as well as when I have it
I have a work around to make this work, by modifying the XSD like the one below
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.learnjava.com"
xmlns="http://www.learnjava.com"
elementFormDefault="qualified">
<xs:element name="school">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="departments">
<xs:complexType>
<xs:sequence>
<xs:element name="department" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="hod" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="id" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="students">
<xs:complexType>
<xs:sequence>
<xs:element name="student" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="dept" type="xs:integer"/>
</xs:sequence>
<xs:attribute name="id" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
but as an XML novice, I am curious to know what is wrong in the earlier XSD
PS:
1. I'm using http://www.utilities-online.info/xsdvalidation/#.VYpP8vmqqko to validate XML against the XSD.
2. I observe the same error in Altova XML Spy editor as well.
the problem is that the attribute id has been declared global(direct child of xs:schema). therefore, the attribute id should be qualified with the namespaces http://www.learnjava.com. Notice that id is not the same thing as http://www.learnjava.com:id
If you don't want that the attribute id belong to the namespace:
you should use a local attribute declaration
In your schema document, change
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.learnjava.com"
xmlns="http://www.learnjava.com"
elementFormDefault="qualified"
attributeFormDefault="qualified">
to
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.learnjava.com"
xmlns="http://www.learnjava.com"
elementFormDefault="qualified"
>
Update:
If you want to use global attribute declaration, then your xml instance document would look like the following:
<p:school xmlns:p="http://www.learnjava.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.learnjava.com ex2.xsd">
<p:name>TAMUC</p:name>
<p:departments>
<p:department p:id="1001">
<p:name>Computer Science</p:name>
</p:department>
<p:department p:id="1002">
<p:name>Social Science</p:name>
<p:hod>Jeff</p:hod>
</p:department>
</p:departments>
<p:students>
<p:student p:id="5001">
<p:name>Frank</p:name>
<p:dept>1001</p:dept>
</p:student>
<p:student p:id="5002">
<p:name>Paul</p:name>
<p:dept>1001</p:dept>
</p:student>
</p:students>
</p:school>

How to add inline schema in java with xml

I make xml file using Jaxb from a xml schema my existing xml file looks like
<transaction>
<id>
<in>computer</in>
<sn>1234567</sn>
<book>JAVA</book>
<author>klen</author>
</id>
<data>
<dateTime>2011-06-24T17:08:36.3727674+05:30</dateTime>
<key>Err</key>
</data>
</transaction>
but I want to add inline schema before <id> node
My schema is looking like
<xs:schema id="transaction" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="transaction" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="id">
<xs:complexType>
<xs:sequence>
<xs:element name="in" type="xs:string" minOccurs="0" />
<xs:element name="sn" type="xs:string" minOccurs="0" />
<xs:element name="book" type="xs:string" minOccurs="0" />
<xs:element name="author" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="data">
<xs:complexType>
<xs:sequence>
<xs:element name="dateTime" type="xs:dateTime" minOccurs="0" />
<xs:element name="key" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="productData">
<xs:complexType>
<xs:sequence>
<xs:element name="dateTime" type="xs:dateTime" minOccurs="0" />
<xs:element name="key" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
now I want to add this before node under node.
Is it possible using Jaxb in first time?I cannot generate xml file with inline schema using jaxb.Due to the large size of my xml I cannot do this using Dom parser.Presently I try that at first generate xml file with data using jaxb and then rewrite the xml file and add schema under <transaction> node before <id> node.
I will prefer sun provided api.I am new in java so if some codesnips will be added it will be help full for me.

XSD validation error using choices

I need either element A or B or both. If i use choices, then it throws an exception Element 'A' cannot have character [children], because the type's content type is element-only.
How to achieve the desired result.
<xsd:complexType>
<xsd:sequence>
<xsd:element name="A">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="C"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="B"/>
</xsd:sequence>
</xsd:complexType>
sample XML is
<start>
<A>
<C>hhg</C>
</A>
</start>
<start>
<A>
<C>hhg</C>
</A>
<B>fgeg</B>
</start>
<start>
<B>fergf</B>
</start>
Use minOccurs="0", e.g.:
<xs:element name="A" minOccurs="0">
...
<xs:element name="B" minOccurs="0"/>
For XML:
<root>
<start>
<A>
<C>hhg</C>
</A>
</start>
<start>
<A>
<C>hhg</C>
</A>
<B>fgeg</B>
</start>
<start>
<B>fergf</B>
</start>
</root>
Appropriate XSD should be:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="start">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="A">
<xs:complexType>
<xs:sequence>
<xs:element name="C" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="0" name="B" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="test">
<xs:choice>
<xs:element name="A">
<xs:complexType>
<xs:sequence>
<xs:element name="C"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="B"/>
</xs:choice>
</xs:complexType>
</xs:schema>
This is validated ok in Oxygen ...

Categories