Java 使用JAXB的多态XML绑定

Java 使用JAXB的多态XML绑定,java,xml,jaxb,Java,Xml,Jaxb,以下是我试图做的: XML是这样的: <Doctype1> <Outter> <Inner> <ProblemType> <foo>...</foo> <baz>...</baz> </ProblemType> </Inner> <

以下是我试图做的:

XML是这样的:

<Doctype1>
    <Outter>
        <Inner>
          <ProblemType>
              <foo>...</foo>
              <baz>...</baz>
          </ProblemType>
        </Inner>
    </Outter>
</Doctype1>

首先,您将如何在Java中实现这样的结构?
DoctypeX
ProblemTypeX
之间有一定的距离,因此不能直接进行多边形化

可能具有以下结构(非常伪代码):

这种结构将适合您的XML。您可能可以使用
@xmlementwrapper
避免
Outer1
/
Outer2
,但仍然需要
Inner1
/
Inner2

@xmlacestortype(xmlacestype.NONE)
  @XmlAccessorType(XmlAccessType.NONE)
    public class Doc1 {

        @XmlElement(type = Outter1.class, name = "Outter")
        private List<Outter> outters;

        public static class Outter1 extends Outter {

            @Override
            @XmlElement(type = Inner1.class, name = "Inner")
            public List<Inner> getInner() {
                return super.getInner();
            }

            @Override
            public void setInner(List<Inner> innards) {
                super.setInner(innards);
            }

            public static class Inner1 extends Inner<ProblemType1> {

                @Override
                @XmlElement(type = ProblemType1.class, name = "ProblemType")
                public List<ProblemType> getProblemTypes() {
                    return super.getProblemTypes();
                }

                @Override
                public void setProblemTypes(List<ProblemType> problemTypes) {
                    super.setProblemTypes(problemTypes);
                }
            }
        }
    }
公共类文档1{ @XmlElement(type=Outter1.class,name=“Outter”) 私人上市公司; 公共静态类Outter1扩展了Outter{ @凌驾 @XmlElement(type=Inner1.class,name=“Inner”) 公共列表getInner(){ 返回super.getInner(); } @凌驾 公共无效设置内部(列出内部){ 超级内胆(内脏); } 公共静态类Inner1扩展了内部{ @凌驾 @XmlElement(type=ProblemType1.class,name=“ProblemType”) 公共列表getProblemTypes(){ 返回super.getProblemTypes(); } @凌驾 public void setProblemTypes(列出problemTypes){ super.setProblemTypes(problemTypes); } } } }
其他类

public class Doc2 {

    @XmlElement(type = Outter2.class, name= "Outter")
    private List<Outter> outters;

    public static class Outter2 extends Outter {

        @Override
        @XmlElement(type = Outter2.class, name = "Inner")
        public List<Inner> getInner() {
            return super.getInner();
        }

        @Override
        public void setInner(List<Inner> innards) {
            super.setInner(groups);
        }

        public static class Inner1 extends Inner<ProblemType2> {
            @Override
            @XmlElement(type = ProblemType2.class, name = "ProblemType")
            public List<ProblemType> getProblemTypes() {
                return super.getProblemTypes();
            }

            @Override
            public void setProblemTypes(List<ProblemType> transactions) {
                super.setProblemTypes(transactions);
            }
        }
    }
}
公共类Doc2{
@XmlElement(type=Outter2.class,name=“Outter”)
私人上市公司;
公共静态类Outter2扩展了Outter{
@凌驾
@XmlElement(type=Outter2.class,name=“Inner”)
公共列表getInner(){
返回super.getInner();
}
@凌驾
公共无效设置内部(列出内部){
super.setInner(组);
}
公共静态类Inner1扩展了内部{
@凌驾
@XmlElement(type=ProblemType2.class,name=“ProblemType”)
公共列表getProblemTypes(){
返回super.getProblemTypes();
}
@凌驾
public void setProblemTypes(列出事务){
super.setProblemTypes(事务);
}
}
}
}
我花了一些时间试图减少它,但它似乎没有响应XmlAccesorType.FIELD。如果我使用与super相同的属性名,这并不重要

这是对的后续操作,目的是尝试使用保存几行。由于
Outter
类本身似乎没有任何意义,并且它仅用作
内部
类的容器,因此可以避免:

请尝试以下操作:

@XmlAccessorType(XmlAccessType.NONE)
public class Doc1 {

        @XmlElementWrapper(name = "Outter")
        @XmlElement(type = Inner1.class, name = "Inner")
        public List<Inner> getInner() {
            return super.getInner();
        }

        @Override
        public void setInner(List<Inner> innards) {
            super.setInner(innards);
        }

        public static class Inner1 extends Inner<ProblemType1> {

            @Override
            @XmlElement(type = ProblemType1.class, name = "ProblemType")
            public List<ProblemType> getProblemTypes() {
                return super.getProblemTypes();
            }

            @Override
            public void setProblemTypes(List<ProblemType> problemTypes) {
                super.setProblemTypes(problemTypes);
            }
        }
}
@xmlacessortype(xmlacesstype.NONE)
公共类文档1{
@XmlElementWrapper(name=“Outter”)
@XmlElement(type=Inner1.class,name=“Inner”)
公共列表getInner(){
返回super.getInner();
}
@凌驾
公共无效设置内部(列出内部){
超级内胆(内脏);
}
公共静态类Inner1扩展了内部{
@凌驾
@XmlElement(type=ProblemType1.class,name=“ProblemType”)
公共列表getProblemTypes(){
返回super.getProblemTypes();
}
@凌驾
public void setProblemTypes(列出problemTypes){
super.setProblemTypes(problemTypes);
}
}
}
但是,请注意,这现在是一个列表,而不是列表列表。因此,在这种结构下,这仍然是可能的:

<Doctype1>
    <Outter>
        <Inner>
          <ProblemType .../>
        </Inner>
        <Inner>
          <ProblemType .../>
        </Inner>
    </Outter>
</Doctype1>

但这不是:

<Doctype1>
    <Outter>
        <Inner>
          <ProblemType .../>
        </Inner>
    </Outter>
    <Outter>
        <Inner>
          <ProblemType .../>
        </Inner>
    </Outter>
</Doctype1>


我更新了问题描述。我昨晚意识到它不是很清楚,所以我更新了它。刚才你的想法可能还有一些优点。只有“问题类型”需要改变,但如果不按你说的做,我看不出有什么办法可以做到。@ChristianBongiorno我已经检查了你的编辑-我认为这对我的答案没有影响。我的观点仍然站得住脚。您将需要多形式的中间类。我看没有别的办法了。试着想想用Java怎么做,你可能是对的。我自己想不出别的办法,但我想我会把它扔出去,看看是否有比我更聪明的人能做到answer@ChristianBongiorno布莱斯·道格汉可能知道得更多,他肯定知道。嗯,但他只是随便问一些电子邮件问题吗?你能不能也发一下
Doc2
?最好让它成为一个答案——接受我的,接受你的。(想想未来的读者。)完成了。不确定它是否有助于未来的读者,但可以。我想给你们一些道具,让你们给我一些验证。我将继续调查各种可能性。这可能会有所帮助,也是正确的做法。干得好。:)我转载了这个问题的一个变体,它确实更准确地回答了这个问题。子类的东西“工作”,但它的丑陋,需要我重写的愚蠢的原因看起来不错的方法。做得好。同时尝试使用
@xmlementwrapper
,也许您可以保存一个级别(即
Outter
)。发布后续信息?我想保留一些台词。哦,Outter确实有意义。它包含15个值,为了简洁起见我省略了:)这有关系吗?让我给你个机会go@ChristianBongiorno好的,那么你不能忽略它,对不起。:)
public class Doc2 {

    @XmlElement(type = Outter2.class, name= "Outter")
    private List<Outter> outters;

    public static class Outter2 extends Outter {

        @Override
        @XmlElement(type = Outter2.class, name = "Inner")
        public List<Inner> getInner() {
            return super.getInner();
        }

        @Override
        public void setInner(List<Inner> innards) {
            super.setInner(groups);
        }

        public static class Inner1 extends Inner<ProblemType2> {
            @Override
            @XmlElement(type = ProblemType2.class, name = "ProblemType")
            public List<ProblemType> getProblemTypes() {
                return super.getProblemTypes();
            }

            @Override
            public void setProblemTypes(List<ProblemType> transactions) {
                super.setProblemTypes(transactions);
            }
        }
    }
}
@XmlAccessorType(XmlAccessType.NONE)
public class Doc1 {

        @XmlElementWrapper(name = "Outter")
        @XmlElement(type = Inner1.class, name = "Inner")
        public List<Inner> getInner() {
            return super.getInner();
        }

        @Override
        public void setInner(List<Inner> innards) {
            super.setInner(innards);
        }

        public static class Inner1 extends Inner<ProblemType1> {

            @Override
            @XmlElement(type = ProblemType1.class, name = "ProblemType")
            public List<ProblemType> getProblemTypes() {
                return super.getProblemTypes();
            }

            @Override
            public void setProblemTypes(List<ProblemType> problemTypes) {
                super.setProblemTypes(problemTypes);
            }
        }
}
<Doctype1>
    <Outter>
        <Inner>
          <ProblemType .../>
        </Inner>
        <Inner>
          <ProblemType .../>
        </Inner>
    </Outter>
</Doctype1>
<Doctype1>
    <Outter>
        <Inner>
          <ProblemType .../>
        </Inner>
    </Outter>
    <Outter>
        <Inner>
          <ProblemType .../>
        </Inner>
    </Outter>
</Doctype1>