I’m working on a project where I need to create an XSD file from our Java model. The problem is I can’t figure out how to represent interfaces in the XSD. Here’s what I’m dealing with:
An interface with two implementations
An object with a field of the interface type
I tried using JAXB to generate the XSD, but it gave me errors about not being able to handle interfaces.
Is there a way to show in the XSD that my object can contain either of the interface implementations? I know about xsd:choice, but I’d prefer a solution that doesn’t need updating when new classes implement the interface.
Here’s a simple code example of what I’m working with:
interface Animal {
void makeSound();
}
class Dog implements Animal {
public void makeSound() {
System.out.println("Woof");
}
}
class Cat implements Animal {
public void makeSound() {
System.out.println("Meow");
}
}
class Farm {
private Animal animal;
// getters and setters
}
Any ideas on how to represent this in XSD? Thanks for your help!
I’ve faced similar challenges when working with XSD and Java interfaces. While JAXB struggles with interfaces, there are workarounds. One approach that has worked for me is utilizing an Adapter pattern. In this approach, you create an adapter class that wraps the interface and its implementations. For instance, you can create an AnimalAdapter class and adjust your Farm class to use this adapter instead of directly referencing the interface. This allows JAXB to generate an XSD for the concrete adapter class. Although you’ll have to manage conversion between Animal and AnimalAdapter in your code, this solution enables flexibility without needing to update the XSD each time a new implementation is added. Hope this helps!
Have you considered using XML Schema’s abstract types? This approach can be quite effective for representing interfaces in XSD. Here’s how it works: define an abstract complex type for your Animal interface, then create concrete types for Dog and Cat that extend this abstract type. In your Farm element, you can then use the abstract Animal type. This method allows for extensibility without modifying the XSD every time you add a new Animal implementation. It does require some additional setup, but it’s a clean solution that maintains the structure of your Java model in the XML representation. I’ve used this technique in several projects with good results. Just be aware that you might need to handle the concrete type resolution in your XML processing code.
hey alexj, u could try using @XmlSeeAlso annotation on ur Animal interface. it lets JAXB know bout the implementing classes. then use @XmlElements in Farm to specify possible animal types. it’s not perfect but works for most cases without changin XSD for new implementations. good luck!