Is it possible to generate a XSD from a JAXB-annotated class?
Asked Answered
T

2

50

I've written a number of classes using JAXB for serialization and I was wondering if there was a way to generate a XSD file for each of these objects based on the annotations. Is there a tool for this?

Something like generate-xsd com/my/package/model/Unit.java would be awesome. Does anything exist to do this?

Transact answered 27/8, 2011 at 1:52 Comment(0)
E
77

Yes, you can use the generateSchema method on JAXBContext:

JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
SchemaOutputResolver sor = new MySchemaOutputResolver();
jaxbContext.generateSchema(sor);

You leverage an implementation of SchemaOutputResolver to control where the output goes:

public class MySchemaOutputResolver extends SchemaOutputResolver {

    public Result createOutput(String namespaceURI, String suggestedFileName) throws IOException {
        File file = new File(suggestedFileName);
        StreamResult result = new StreamResult(file);
        result.setSystemId(file.toURI().toURL().toString());
        return result;
    }

}
Estellaestelle answered 27/8, 2011 at 10:53 Comment(5)
Also, see the Maven plugin for this: #7251958Transact
Hi, this method does nothing for me (createOutput never called). I'm using this implementation: com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl. Any thoughts? - ThanksArillode
Yep, tried both breakpoint and System.err.print. I'm creating the context from package name using jaxb.index file. My context works well otherwise (it marshalls object graphs without any problem).Arillode
It is caused by implementing an interface on one of the JAXB annotated classes. It is strange because the interface only contains one method (a getter) and it is not related to a JAXB property. - So the example is excellent, no additional magic is required, but the schema generator is much more picky than the marshaller.Arillode
I think it'd be better to use result.setSystemId(file.getAbsolutePath()); instead of result.setSystemId(file.toURI().toURL().toString()); I had a file not found exception when use it.Rankin
E
0

I have modified the answer a bit so we can pass our class and also get the path where XSD file has been created:

public class SchemaGenerator {
    public static void main(String[] args) throws JAXBException, IOException {
        JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
        SchemaOutputResolver sor = new MySchemaOutputResolver();
        jaxbContext.generateSchema(sor);
    }
}

class MySchemaOutputResolver extends SchemaOutputResolver {
    @SneakyThrows
    public Result createOutput(String namespaceURI, String suggestedFileName) {
        File file = new File(suggestedFileName);
        StreamResult result = new StreamResult(file);
        result.setSystemId(file.getAbsolutePath());
        System.out.println(file.getAbsolutePath());
        return result;
    }
}
Embower answered 1/7, 2021 at 6:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.