Inheritance JAXB继承-对注释中声明的子类型进行解组?

Inheritance JAXB继承-对注释中声明的子类型进行解组?,inheritance,jaxb,moxy,subclass,Inheritance,Jaxb,Moxy,Subclass,我想根据属性值将JAXB bean分解成子类 莫西可以做到这一点: @XmlDiscriminatorNode("@type") public static class ActionDef extends ContainerOfStackableDefs { ... } @XmlDiscriminatorValue("cli") public static class CliActionDef extends ActionDef { /** CLI command. EL. */

我想根据属性值将JAXB bean分解成子类

莫西可以做到这一点:

@XmlDiscriminatorNode("@type")
public static class ActionDef extends ContainerOfStackableDefs { ... }

@XmlDiscriminatorValue("cli")
public static class CliActionDef extends ActionDef {
    /** CLI command. EL. */
    @XmlAttribute public String command;
}
但是,
JAXBContext
需要所有指定的类。在“根”类之外的其他地方定义它有点不舒服

我希望有这样的事情:

@XmlDiscriminatorNode("@type")
@XmlSubClasses({ CliActionDef.class, XsltActionDef.class, ... })
public static class ActionDef extends ContainerOfStackableDefs { ... }
我不想进入
XmlAdapter
s,这是一项琐碎的任务,应该有琐碎的解决方案

我是否可以使用spec或MOXy扩展来简单地列出根类中的子类?

否则,我将使用Jandex自动查找子类。毕竟,莫西也能做到;-)


更新:记录在案,然后我

Descriptor: XMLDescriptor(org.jboss.loom.migrators._ext.MigratorDefinition$ActionDef --> [])
at org.eclipse.persistence.exceptions.DescriptorException.missingClassIndicatorField(DescriptorException.java:957)
    ...
这里描述的是:

简而言之:不要将MOXy解组到与
@xmlscriminatornode(“@name”)
中的名称相同的命名属性。如果您这样做了,那么就让它
@XmlReadOnly
,而不要让类抽象


更新:我还是不能让它工作。我一直在学习基础课程。由MOXy处理,而不是JDK的impl

我的代码:

    <action type="xslt" var="addAction" ...>
    </action>

    <action type="manual">
        ...
    </action>
简而言之:缺少
java.lang.String
:-o可解


此外,我还创建了一个最简单的测试用例:

public class JaxbInheritanceTest {    
    @Test
    public void testUnmarshall() throws JAXBException{
        final Unmarshaller marshaller = XmlUtils.createJaxbContext(Root.class).createUnmarshaller();
        Root root = (Root) marshaller.unmarshal( new StringReader(
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root><sub disc=\"foo\"/><sub disc=\"bar\"/></root>") );

        boolean rightClass = (DiscFoo.class.isAssignableFrom( root.subs.get(0).getClass() ));
        Assert.assertTrue( "base elements go into subclasses", rightClass );

        rightClass = (DiscBar.class.isAssignableFrom( root.subs.get(1).getClass() ));
        Assert.assertTrue( "base elements go into subclasses", rightClass );
    }

    @XmlRootElement
    public static class Root {
        @XmlElement(name = "sub")
        List<Base> subs;
    }

    @XmlDiscriminatorNode("@disc")
    @XmlSeeAlso({DiscFoo.class, DiscBar.class})
    public static abstract class Base {}

    @XmlRootElement @XmlDiscriminatorValue("foo")
    public static class DiscFoo {}

    @XmlRootElement @XmlDiscriminatorValue("bar")
    public static class DiscBar {}

}
public类JaxbInheritanceTest{
@试验
public void testUnmarshall()抛出JAXBEException{
final Unmarshaller marshaller=XmlUtils.createJaxbContext(Root.class.createUnmarshaller();
根根=(根)封送拆收器.unmarshal(新StringReader)(
“\n”);
布尔rightClass=(DiscFoo.class.isAssignableFrom(root.subs.get(0.getClass());
Assert.assertTrue(“基本元素进入子类”,rightClass);
rightClass=(DiscBar.class.isAssignableFrom(root.subs.get(1.getClass());
Assert.assertTrue(“基本元素进入子类”,rightClass);
}
@XmlRootElement
公共静态类根{
@xmlement(name=“sub”)
列出潜艇;
}
@XmlDiscriminatorNode(“@disc”)
@XMLSEEALTO({DiscFoo.class,DiscBar.class})
公共静态抽象类基类{}
@XmlRootElement@XmlDiscriminatorValue(“foo”)
公共静态类DiscFoo{}
@XmlRootElement@XmlDiscriminatorValue(“条”)
公共静态类DiscBar{}
}
但这也给了我2x
Base
。它由MOXy签入调试器处理。

这里出了什么问题?

您可以使用
@xmlsee也
(javax.xml.bind.annotation)注释来进行此操作

@xmlscriminatornode(“@type”)
@XMLSEEAL({CliActionDef.class,XsltActionDef.class,…})
公共静态类ActionDef扩展了ContainerOfStackableDefs{…}

更新

您在最新更新中看到的问题是由于未将
@XmlDescriminatorNode
放在继承层次结构中的根类上造成的。当我使用
@xmltransive
从继承层次结构中删除
ContainerOfStackableDefs
时,一切正常(请参阅:)

演示

导入java.io.File;
导入java.util.*;
导入javax.xml.bind.*;
导入javax.xml.bind.annotation.*;
导入org.eclipse.persistence.oxm.annotations.*;
公开课演示{
@XmlTransient
公共静态类ContainerOfStackableDefs{
}
@XmlDiscriminatorNode(“类型”)
@XMLSEEAL({ManualActionDef.class,FileBasedActionDef.class,XsltActionDef.class})
公共静态类ActionDef扩展了ContainerOfStackableDefs{
//@XmlAttribute
//@XmlReadOnly
公共字符串typeVal;//为类型,导致异常。
//公共财产清单;
//@XmlAnyAttribute
publicmap attribs=newhashmap();
}
@XmlDiscriminatorValue(“手动”)
公共静态类手册ActionDef扩展ActionDef{
}
@XmlDiscriminatorValue(“基于文件”)
公共静态类FileBasedActionDef扩展了ActionDef{
/**路径掩码。类似蚂蚁的通配符,EL*/
@XmlAttribute公共字符串路径掩码;
/**存储结果的位置。可以是dir或file.EL*/
@XmlAttribute公共字符串dest;
}
@XmlDiscriminatorValue(“xslt”)
公共静态类XsltActionDef扩展了FileBasedActionDef{
/**XSLT模板路径*/
@XmlAttribute公共字符串xslt;
}
@XmlRootElement
公共静态类根{
@xmlement(name=“actionDef”)
公开清单行动;
}
公共静态void main(字符串[]args)引发异常{
JAXBContext jc=JAXBContext.newInstance(Root.class);
Unmarshaller Unmarshaller=jc.createUnmarshaller();
File xml=新文件(“src/forum17453793/input.xml”);
Root=(Root)unmarshaller.unmarshal(xml);
Marshaller=jc.createMarshaller();
setProperty(marshaller.JAXB_格式化的_输出,true);
marshaller.marshall(root,System.out);
}
}
input.xml/Output



@OndraŽižka-没问题<在JAXB 2.1中引入了代码> @ XMLSEEXION/<代码>以解决这个问题。BTW,您是否考虑添加JANDEX解决方案,以用于当我事先不真正知道子类的情况下?例如插件等@OndraŽižka-您介意为此输入一个增强请求吗?:以及(为这个问题滥用SO的借口)-是否考虑/正在进行一些CDI和MOXy集成?由CDI解析各种工厂方法、适配器等可能很酷。关于继承根,我认为在任意级别声明JAXB的层次结构根是有意义的。我需要
ContainerOfStackableDefs
,因为它捕获了JAXB加载的其他结构的公共特性。对于增强请求,这是否可以省略?
Exception Description: Missing class for indicator field value [manual] of type [class java.lang.String].
Descriptor: XMLDescriptor(org.jboss.loom.migrators._ext.MigratorDefinition$ActionDef --> [])
at org.eclipse.persistence.exceptions.DescriptorException.missingClassForIndicatorFieldValue(DescriptorException.java:938)
at org.eclipse.persistence.internal.oxm.QNameInheritancePolicy.classFromRow(QNameInheritancePolicy.java:264)
public class JaxbInheritanceTest {    
    @Test
    public void testUnmarshall() throws JAXBException{
        final Unmarshaller marshaller = XmlUtils.createJaxbContext(Root.class).createUnmarshaller();
        Root root = (Root) marshaller.unmarshal( new StringReader(
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root><sub disc=\"foo\"/><sub disc=\"bar\"/></root>") );

        boolean rightClass = (DiscFoo.class.isAssignableFrom( root.subs.get(0).getClass() ));
        Assert.assertTrue( "base elements go into subclasses", rightClass );

        rightClass = (DiscBar.class.isAssignableFrom( root.subs.get(1).getClass() ));
        Assert.assertTrue( "base elements go into subclasses", rightClass );
    }

    @XmlRootElement
    public static class Root {
        @XmlElement(name = "sub")
        List<Base> subs;
    }

    @XmlDiscriminatorNode("@disc")
    @XmlSeeAlso({DiscFoo.class, DiscBar.class})
    public static abstract class Base {}

    @XmlRootElement @XmlDiscriminatorValue("foo")
    public static class DiscFoo {}

    @XmlRootElement @XmlDiscriminatorValue("bar")
    public static class DiscBar {}

}