Reputation: 367
A very generalized and simplified scenario description:
Now the schema defines complex types A, B and C. The schema specifies that XML document must have top level element A and this can contain multiple B and this can optionally include C. I create JAXB instance for B and absolutely want to validate this against the complex type definition in the XSD before nesting it under A. However validation of this will fail if I validate against the entire XSD.
Questions: How to validate JAXB instance against only a part of the XSD from which its class has been generated from?
How about using schemagen to generate schema from the JAXB class which instance I want to validate and then validate against that? Do you think that can work? Any other ideas?
I have no previous experience with schemagen and will start prototyping of this solution soon.
Note: in reality, the schemas are not as simple as in the above example and the solution of creating some always-valid mock of A is not feasible option. Not to mention that this kind of validation will be on hundred places to say the least.
Upvotes: 0
Views: 628
Reputation: 37
While working with xjc
and schemagen
tools please consider same concept which we use in java. In java, every class is a skeleton and object is an instance. Same as we need to consider XSD as skeleton and XML as instance.
xjc tool:-
Xsd to Java Class
OrUnmarshaling
Consider the below XSD with namespaces for example. The xjc
tool will generate the java class along with package-info and object-factory.
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ir="http://irctc.org/service" targetNamespace="http://irctc.org/service">
<xsd:element name="Customer" type="ir:CustomerType"/>
<xsd:complexType name="CustomerType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="src" type="xsd:string"/>
<xsd:element name="dest" type="xsd:string"/>
<xsd:element name="price" type="xsd:float" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Use below command
D:\>xjc Customer.xsd
parsing a schema...
compiling a schema...
org\irctc\service\CustomerType.java
org\irctc\service\ObjectFactory.java
org\irctc\service\package-info.java
Note :- If you have multiple java class then you can use jaxb.index
file instead of using ObjectFactory.java
.
schemagen tool:-
Java Class to Xsd
OrMarshaling
Let us suppose we want to generate the Xsd file using java class then first we need to create the ObjectFactory.java
Or jaxb.index
file and package-info.java
in the same package where we have the CustomerType.java
.
package org.irctc.service;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlRootElement("Customer")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CustomerType", propOrder = {
"name",
"src",
"dest",
"price"
})
public class CustomerType {
@XmlElement(required = true)
protected String name;
@XmlElement(required = true)
protected String src;
@XmlElement(required = true)
protected String dest;
protected Float price;
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public String getSrc() {
return src;
}
public void setSrc(String value) {
this.src = value;
}
public String getDest() {
return dest;
}
public void setDest(String value) {
this.dest = value;
}
public Float getPrice() {
return price;
}
public void setPrice(Float value) {
this.price = value;
}
}
Use below command
D:\>schemagen org.irctc.service.CustomerType
Note: Writing D:\schema1.xsd
The above command will generate the xsd file. The package of java class will considered as xsd namespaces.
The above details are only for understanding marshaling and unmarshaling process using tools in Jax-B API.
For more details , check below examples
Java-XML mapping with Jax-B 2.0
Upvotes: 0
Reputation: 11
create separate schema for element you want to validate, where this element is on root level. to workaround missing @xmlRoottag see 101 ways to marshal objects with JAXB
Upvotes: 1
Reputation: 367
Well it turns out that using xsi:type let's one accomplish this.
http://www.w3.org/TR/xmlschema-1/#xsi_type
Upvotes: 0