对相似的xml模式重用JAXB类

时间:2019-06-26 22:55:07

标签: java xml parsing jaxb sax

我有以下XML,对于每种XML,我都有使用JAXB建模的相应Java类。

XML 1:

<counts at="2019-06-27 09:54:31">
    <media id="1" start="1" finish="1000" timeZone="NZST">
        <count id="1" value="1" at="2019-06-27 09:54:31" duration="5"/>
        <count id="2" value="2" at="2019-06-27 09:54:31" duration="5"/>
        <count id="3" value="3" at="2019-06-27 09:54:31" duration="5"/>
    </media>
</counts>

XML 2:

<tags at="2019-06-27 09:54:31">
    <media id="1" start="1" finish="1000" timeZone="NZST">
        <tag id="1" value="1" at="2019-06-27 09:54:31" visible="true" />
        <tag id="2" value="2" at="2019-06-27 09:54:31" visible="true" />
        <tag id="3" value="3" at="2019-06-27 09:54:31" visible="true" />
    </media>
</tags>

XML 3:

<trajectories at="2019-06-27 09:54:31">
    <media id="1" start="1" finish="1000" timeZone="NZST">
        <trajectory id="1" value="1" at="2019-06-27 09:54:31" />
        <trajectory id="2" value="2" at="2019-06-27 09:54:31" />
        <trajectory id="3" value="3" at="2019-06-27 09:54:31" />
    </media>
</trajectories>

由于所有XML中的大多数元素或多或少都相同,除了<count>, <tag> and <trajectory>之外。 有没有一种方法可以为<counts>, <tags>, <trajectories> and <media>提取类?

理想情况下,我想要类似的东西:

class CountsTagsTrajectories<T extends CommonObjectsOfMedia> {
    private Media<T> media;
}


class Media<T> {
    private List<T> listOfObjects;
}

class Count extends CommonObjectsOfMedia {
    ...
    ...
    ...
}

class Tag extends CommonObjectsOfMedia {
    ...
    ...
    ...
}

class Trajectory extends CommonObjectsOfMedia {
    ...
    ...
    ...
}

这种方法可行吗?否则我将不得不上以下课程:

Counts > CountMedia > Count
Tags > TagMedia > Tag
Trajectories > TrajectoryMedia > Trajectory

我现在试图抽象类的问题是,我需要在@XmlElement中定义一个名称,无论是计数/计数,标签/标记还是轨迹/轨迹。

注意:我见过这个post,但是它的作用是将所有可能的“ CommonObjectsOfMedia”列表添加到Media类,而这并不是我想要的。

1 个答案:

答案 0 :(得分:2)

您在正确的道路上。有两点可以改进。

  1. 媒体结构具有几乎相同且使用不同名称的标签,轨迹和计数。我们可以解决:

首先拥有CommonObjectsOfMedia

@XmlAccessorType(XmlAccessType.FIELD)
public class CommonObjectsOfMedia {

    @XmlAttribute
    private String id;
    @XmlAttribute
    private String value;
    @XmlAttribute
    private String at;

}

然后,媒体内部的标签具有共同的额外属性。看起来像:

@XmlAccessorType(XmlAccessType.FIELD)
public class MediaTag extends CommonObjectsOfMedia {

    @XmlAttribute
    private boolean visible;
}

类似计数:

@XmlAccessorType(XmlAccessType.FIELD)
public class MediaCount extends  CommonObjectsOfMedia {

    @XmlAttribute
    private String duration;
}

和轨迹只有共同点。

现在,让我们创建Media类,该类将能够处理它们的任何情况。魔术来自@XmlElements

@XmlAccessorType(XmlAccessType.FIELD)
public class Media {

    @XmlAttribute
    private String id;
    @XmlAttribute
    private String start;
    @XmlAttribute
    private String finish;
    @XmlAttribute
    private String timeZone;

    @XmlElements ({
        @XmlElement(name="tag", type = MediaTag.class),
        @XmlElement(name="trajectory", type = CommonObjectsOfMedia.class),
        @XmlElement(name="count", type = MediaCount.class),
    })
    private List<CommonObjectsOfMedia> commonObjectsOfMedia;
}

我将创建一个演示类,该类将同时显示所有案例的解组。 xml看起来像这样:

<someroot at="2019-06-27 09:54:31">
    <media id="1" start="1" finish="1000" timeZone="NZST">
        <tag id="1" value="1" at="2019-06-27 09:54:31" visible="true" />
        <tag id="2" value="2" at="2019-06-27 09:54:31" visible="true" />
        <tag id="3" value="3" at="2019-06-27 09:54:31" visible="true" />
    </media>
    <media id="1" start="1" finish="1000" timeZone="NZST">
        <trajectory id="1" value="1" at="2019-06-27 09:54:31" />
        <trajectory id="2" value="2" at="2019-06-27 09:54:31" />
        <trajectory id="3" value="3" at="2019-06-27 09:54:31" />
    </media>
    <media id="1" start="1" finish="1000" timeZone="NZST">
        <count id="1" value="1" at="2019-06-27 09:54:31" duration="5"/>
        <count id="2" value="2" at="2019-06-27 09:54:31" duration="5"/>
        <count id="3" value="3" at="2019-06-27 09:54:31" duration="5"/>
    </media>
</someroot>

和这样的根类:

@XmlRootElement
public class Someroot {

    @XmlElement
    private List<Media> media;
}

这将正确解组。然后转到项目2。

根的名称不同,但内部结构相同。也许您也想解决此问题。可以像下面的回复中所示:Can JAXB handle multiple "root" elements?