如何以适合JAXB和Java的方式在XML模式中表示对象的层次结构

如何以适合JAXB和Java的方式在XML模式中表示对象的层次结构,java,jaxb,xsd,object-graph,Java,Jaxb,Xsd,Object Graph,我有一个表示分类法的数据模型。分类法是类别的层次结构,例如 Food +- Pasta +- Spaghetti 我想将此表示为 <taxonomy> <category id="cat001" name="Food"/> <category id="cat002" name="Pasta"> <parentCategory> <category ref="cat001"/> <

我有一个表示分类法的数据模型。分类法是类别的层次结构,例如

Food
 +- Pasta
     +- Spaghetti
我想将此表示为

<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>
此外,如果我的分类法不是一个严格的树,而是一个图形,其中可能有不止一个父关系,比如意大利面和面条都属于意大利面,那该怎么办

<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>
使用JAXB,我想生成如下内容

class Category {
  String name;
  Category parentCategory;
}
class Category {
  String name;
  List<Category> parentCategories;
}
注意,Java代码的简化仅用于说明目的。对于JAXB代码生成,我不介意使用容器对象,例如parentCategory具有category属性,建议从Java对象开始

对于您的用例,我建议从您想要的对象模型开始,然后应用它将其映射到所需的XML表示。下面的例子应该会有所帮助:

XML模式

如果需要XML模式,可以从JAXB模型生成一个

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;
            }

        });
    }

}
共享引用

您可以使用@XmlID和@XmlIDREF在XML文档中创建基于键的引用


如果您对JAXB注释感兴趣,我建议您使用Vogel的教程:另外,我认为解释上面的演示代码片段的目的与Vihung的问题有关会很有帮助。特别是因为该示例对您提到的JAXB注释没有任何作用@布莱斯·道格汉:你回答了JAXB的每一个问题吗@torbinsky-Vogel的教程很好,我还有一个更深入地介绍JAXB的博客。我已经更新了我的答案,以便更好地定位代码片段。@DavidGrant-不是每个问题,但我昨天确实回答了我的第1000个问题。我是JAXB专家组和EclipseLink JAXB MOXy负责人的一部分。我发现有关JAXB的问题是如何使用JAXB的一个有用的指示器,也是找出痛点在哪里以及人们需要什么扩展的一个有用的方法。@BlaiseDoughan我已经知道你的资历了——我在开你的玩笑;