1

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

Vihung
  • 12,947
  • 16
  • 64
  • 90

1 Answers1

1

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.

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • If you are interested in JAXB annotations I would suggest Vogel's tutorial: http://www.vogella.com/articles/JAXB/article.html Also, I think it would be helpful to explain what the above Demo code snippet's purpose is in relation to Vihung's question. Especially since the example does nothing with the JAXB annotations that you mentioned! – torbinsky Sep 21 '12 at 15:52
  • @Blaise Doughan: Do you answer every JAXB question on SO? :) – David Grant Sep 21 '12 at 15:53
  • @torbinsky - Vogel's tutorial is good, I also have a blog that covers JAXB in more depth (http://blog.bdoughan.com/). I've updated my answer to better position the code snippet. – bdoughan Sep 21 '12 at 16:05
  • @DavidGrant - Not every question, but I did answer my 1000th yesterday. I'm part of the JAXB expert group and the EclipseLink JAXB (MOXy) lead. I find questions on SO a useful indicator of how JAXB is being used, and a useful way of finding out where the pain points are and what extensions people need. – bdoughan Sep 21 '12 at 16:09
  • 1
    @BlaiseDoughan I knew your credentials already - I was pulling your leg. ;) – David Grant Sep 21 '12 at 17:21