finrod
finrod

Reputation: 367

JAXB and validation against parts of a schema with schemagen?

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

Answers (3)

Ankit Prakash
Ankit Prakash

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 Or Unmarshaling

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 Or Marshaling

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

Jax-B Hello World Example

Java-XML mapping with Jax-B 2.0

Upvotes: 0

shpelda
shpelda

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

finrod
finrod

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

Related Questions