【问题标题】:Reuse JAXB classes for similar xml schemas为类似的 xml 模式重用 JAXB 类
【发布时间】:2019-06-26 22:55:07
【问题描述】:

我有以下 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>

因为除了&lt;count&gt;, &lt;tag&gt; and &lt;trajectory&gt; 之外,所有XML 中的大多数元素都或多或少相同。 有没有办法为&lt;counts&gt;, &lt;tags&gt;, &lt;trajectories&gt; and &lt;media&gt; 抽象类?

理想情况下,我想要这样的东西:

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 类中,这不是我想要的。

【问题讨论】:

    标签: java xml parsing jaxb sax


    【解决方案1】:

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

    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?

    【讨论】:

    • 感谢您的回答,我最终以完全不同的方法使用 XPath。不过,您的回答回答了我的问题,所以这是您的选择!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    相关资源
    最近更新 更多