将 JAXB 类 重新用于类似的 xml 模式
Reuse JAXB classes for similar xml schemas
我有以下 XMLs,对于每个 XML 我有相应的 Java classes 用 JAXB 建模。
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>
抽象 classes?
理想情况下,我想要这样的东西:
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 {
...
...
...
}
这种方法可行吗?或者我必须有 class 这样的:
Counts > CountMedia > Count
Tags > TagMedia > Tag
Trajectories > TrajectoryMedia > Trajectory
我现在面临的问题是试图抽象 classes 是我需要在@XmlElement 中定义一个名称,无论是 counts/count、tags/tag 还是trajectories/trajectory.
注意:我看过这个 post 但它的作用是将所有可能 "CommonObjectsOfMedia" 的列表添加到媒体 class 而这不是我想要的对于.
你走在正确的道路上。有两点可以改进。
- 媒体结构有tags, trajectory and count 几乎相同,只是名字不同。我们可以处理:
首先,因为你有 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;
}
轨迹只有共同点
现在让我们创建能够处理任何情况的媒体 class。魔法来自@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;
}
我将创建一个演示 class,它将同时显示所有案例的解组。 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>
和根 class 像这样:
@XmlRootElement
public class Someroot {
@XmlElement
private List<Media> media;
}
这将正确解组。然后我们转到第 2 项。
根的名称不同,但内部结构相同。也许你也想解决这个问题。这可以按照此回复中所示完成:Can JAXB handle multiple "root" elements?
我有以下 XMLs,对于每个 XML 我有相应的 Java classes 用 JAXB 建模。
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>
抽象 classes?
理想情况下,我想要这样的东西:
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 {
...
...
...
}
这种方法可行吗?或者我必须有 class 这样的:
Counts > CountMedia > Count
Tags > TagMedia > Tag
Trajectories > TrajectoryMedia > Trajectory
我现在面临的问题是试图抽象 classes 是我需要在@XmlElement 中定义一个名称,无论是 counts/count、tags/tag 还是trajectories/trajectory.
注意:我看过这个 post 但它的作用是将所有可能 "CommonObjectsOfMedia" 的列表添加到媒体 class 而这不是我想要的对于.
你走在正确的道路上。有两点可以改进。
- 媒体结构有tags, trajectory and count 几乎相同,只是名字不同。我们可以处理:
首先,因为你有 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;
}
轨迹只有共同点
现在让我们创建能够处理任何情况的媒体 class。魔法来自@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;
}
我将创建一个演示 class,它将同时显示所有案例的解组。 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>
和根 class 像这样:
@XmlRootElement
public class Someroot {
@XmlElement
private List<Media> media;
}
这将正确解组。然后我们转到第 2 项。
根的名称不同,但内部结构相同。也许你也想解决这个问题。这可以按照此回复中所示完成:Can JAXB handle multiple "root" elements?