我有以下 XML 结构,它正在跨多个 XML 元素对单个概念进行建模。这种格式不受我控制。
<Output>
<Wrapper>
<Channel>
<id>1</id>
<type>x</type>
</Channel>
<Channel>
<id>2</id>
<type>y</type>
</Channel>
<ChannelName>
<id>1</id>
<name>Channel name</name>
</ChannelName>
<ChannelName>
<id>2</id>
<name>Another channel name</name>
</ChannelName>
</Wrapper>
</Output>
我想在我可以控制的数据库中对此建模,并且可以有一个更简单的 Channel
表 id
, type
和 name
领域。因此我想解码成一个 List<Channel>
在 Wrapper
上类。
这可以用 @Xml...
来完成吗?自动注释?我目前正在使用 JAXB 解码为单独的 @XmlElement(name="Channel")
和 @XmlElement(name="ChannelName")
类列表,然后对 transient 进行后处理 ChannelName/name
在 Channel
上但我认为必须有一种更简单的自动化方法来映射这些元素。还是 XSLT 的工作?
了解 XML 以 HTTP 文件 POST 文件的形式出现并且我使用的是 Spring 3、Java 和 Hibernate 可能会有所帮助。我希望在 EclipseLink JAXB (MOXy) 中有所作为可能有帮助:)
最佳答案
@XmlElementWrapper 将完成这项工作:
@XmlElementWrapper(name="Wrapper")
@XmlElement(name="Channel")
private List<Channel> channels;
对于更高级的情况,您可以在 EclipseLink JAXB (MOXy) 中使用 @XmlPath 扩展:
这是我目前所拥有的。我仍在努力消除对辅助对象的需求。此示例需要 EclipseLink JAXB (MOXy) .
模型对象
您的模型对象是:
package example;
import java.util.ArrayList;
import java.util.List;
public class Wrapper {
private List<Channel> channels = new ArrayList<Channel>();
public List<Channel> getChannels() {
return channels;
}
public void setChannels(List<Channel> channels) {
this.channels = channels;
}
}
和:
package example;
import javax.xml.bind.annotation.XmlID;
public class Channel {
private String id;
private String type;
private String name;
@XmlID
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
辅助对象
我目前的解决方案涉及一些辅助对象:
package example.adapted;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import example.Channel;
import example.Wrapper;
@XmlRootElement(name="Output")
@XmlType(propOrder={"channels", "channelNames"})
public class AdaptedWrapper {
private Wrapper wrapper = new Wrapper();
private List<ChannelName> channelNames;
@XmlTransient
public Wrapper getWrapper() {
for(ChannelName channelName : channelNames) {
channelName.getChannel().setName(channelName.getName());
}
return wrapper;
}
@XmlElementWrapper(name="Wrapper")
@XmlElement(name="Channel")
public List<Channel> getChannels() {
return wrapper.getChannels();
}
public void setChannels(List<Channel> channels) {
wrapper.setChannels(channels);
}
@XmlElementWrapper(name="Wrapper")
@XmlElement(name="ChannelName")
public List<ChannelName> getChannelNames() {
return channelNames;
}
public void setChannelNames(List<ChannelName> channelNames) {
this.channelNames = channelNames;
}
}
和:
package example.adapted;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlIDREF;
import example.Channel;
public class ChannelName {
private String name;
private Channel channel;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlIDREF
@XmlElement(name="id")
public Channel getChannel() {
return channel;
}
public void setChannel(Channel channel) {
this.channel = channel;
}
}
演示代码
package example;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import example.adapted.AdaptedWrapper;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(AdaptedWrapper.class);
File xml = new File("input.xml");
Unmarshaller unmarshaller = jc.createUnmarshaller();
AdaptedWrapper adaptedWrapper = (AdaptedWrapper) unmarshaller.unmarshal(xml);
Wrapper wrapper = adaptedWrapper.getWrapper();
for(Channel channel : wrapper.getChannels()) {
System.out.println(channel.getName());
}
}
}
关于java - JAXB 将多个 XML 元素解码为单个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5325362/