I have a data model that represents a taxonomy. The taxonomy is a hierarchy of categories, such as
Food
+- Pasta
+- Spaghetti
I would like to represent this as
<taxonomy>
<category id="cat001" name="Food"/>
<category id="cat002" name="Pasta">
<parentCategory>
<category ref="cat001"/>
</parentCategory>
</category>
<category id="cat003" name="Spaghetti">
<parentCategory>
<category ref="cat002"/>
</parentCategory>
</category>
</taxonomy>
What is the best way to represent this in an XML schema (XSD)?
Also, how can I ensure that when using JAXB, I can get something like
class Category {
String name;
Category parentCategory;
}
Further, what if my taxonomy is not a strict tree, but a graph, where there may be more than one parent relationship, such that Spaghetti comes under Pasta as well as Noodles
<taxonomy>
<category id="cat001" name="Food"/>
<category id="cat002" name="Pasta">
<parentCategories>
<category ref="cat001"/>
</parentCategories>
</category>
<category id="cat003" name="Noodles">
<parentCategories>
<category ref="cat001"/>
</parentCategories>
</category>
<category id="cat004" name="Spaghetti">
<parentCategories>
<category ref="cat002"/> <!-- Pasta -->
<category ref="cat003"/> <!-- Noodles -->
</parentCategory>
</category>
</taxonomy>
and with JAXB, I would want to then generate something like
class Category {
String name;
List<Category> parentCategories;
}
Note, the Java code is simplified for illustration purposes only. With JAXB code generation, I don't mind having a container object, such as parentCategory having a category property
Recommendation - Start From Java Objects
For your use case I would recommend starting with the object model you want and then applying JAXB annotations to map it to the desired XML representation. The following example should help:
XML Schema
If you then need an XML schema you can generate one from your JAXB model.
import java.io.IOException;
import javax.xml.bind.*;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(SpThread.class);
jc.generateSchema(new SchemaOutputResolver() {
@Override
public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
StreamResult result = new StreamResult(System.out);
result.setSystemId(suggestedFileName);
return result;
}
});
}
}
Shared References
You can use @XmlID
and @XmlIDREF
to create key based references within the XML document.