JAXB2: Mapping nested elements into the same Java

2019-02-23 06:53发布

I'm having trouble trying to map nested elements into the same Java class.

XML

What I'm trying to do here is to set id attribute and text element into SlideText class.

<module name="test project">
    <slide id="1">
        <layout>
            <text>hello</text>
        </layout>
    </slide>
</module>

Module class

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Module {
    @XmlAttribute
    private String  name;

    @XmlElements({
        @XmlElement(name = "slide", type = SlideText.class)
    })
    private Slide   slide;
}

Slide class

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class Slide {
    @XmlAttribute
    private String  id;
}

SlideText class

I tried using @XmlElementWrapper on text property, but I get an exception that @XmlElementWrapper can only be applied to a collection.

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SlideText extends Slide {

    // how to map this to layout/text elements?
    private String  text;
}

Is there a way to map <layout><text>hello</text></layout> into SlideText's text property?

Thanks.

UPDATE

To illustrate what I'm trying to accomplish here, the slide can be of any type depending on what layout is used. A module knows it's a slide but it doesn't know what slide it is, which is why I have the abstract Slide class.

Essentially, if this works, I'll be creating SlideImage and SlideTextVideo that extends Slide.

Here's how the actual XML file looks like:-

<module name="test project">
    <slide id="1">
        <layout-text>
            <text>hello</text>
        </layout-text>
    </slide>
</module>
<module name="test project">
    <slide id="2">
        <layout-image>
            <image-path>img.jpg</image-path>
        </layout-image>
    </slide>
</module>
<module name="test project">
    <slide id="3">
        <layout-text-video>
            <text>hello</text>
            <video-path>a.mp4</video-path>
        </layout-text-video>
    </slide>
</module>

标签: java jaxb jaxb2
2条回答
smile是对你的礼貌
2楼-- · 2019-02-23 07:28

Add a new class Layout:

public class SlideText extends Slide {
    @XmlElement
    private Layout layout;
}

public class Layout {
    @XmlAttribute
    private String  text;
}
查看更多
贪生不怕死
3楼-- · 2019-02-23 07:38

If you use EclipseLink JAXB (MOXy) then you can leverage the @XmlPath extension for this (I'm the MOXy tech lead):

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SlideText extends Slide {

    @XmlPath("layout/text/text()")
    private String  text;

}

Using standard JAXB you could leverage an XmlAdapter:

查看更多
登录 后发表回答