[英]JAXB marshaling and unmarshalling multiple XML elements into a single class and reverse
[英]JAXB unmarshalling multiple XML elements into single class
我有以下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>
我想在我可以控制的數據庫中對此進行建模,並且可以使用包含id
, type
和name
字段的更簡單的Channel
表。 因此,我想在Wrapper
類的單個List<Channel>
解組。
這可以通過@Xml...
注釋自動完成嗎? 我目前正在使用JAXB解組成單獨的@XmlElement(name="Channel")
和@XmlElement(name="ChannelName")
類列表,然后在Channel
上對瞬態ChannelName/name
進行后處理,但我認為必須有一種更簡單的自動方式來映射這些元素。 或者它是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());
}
}
}
您可以通過在JAXB中自動執行此過程來節省編碼時間:
使用以下鏈接為XML創建XML模式,將其另存為output.xsd文件: http : //www.xmlforasp.net/CodeBank/System_Xml_Schema/BuildSchema/BuildXMLSchema.aspx
使用JDK從項目根文件夾(。)運行下面的批處理腳本文件(將其命名為output.bat ),因為只有JDK具有xjc.exe工具(填寫必要的詳細信息):
"C:\Program Files\Java\jdk1.6.0_24\bin\xjc.exe" -p %1 %2 -d %3
哪里...
syntax: output.bat %1 %2 %3
%1 = target package name
%2 = full file path name of the generated XML schema .xsd
%3 = root source folder to store generated JAXB java files
例:
假設項目文件夾的組織如下:
.
\_src
從(。)命令提示符處運行以下命令:
output.bat com.project.xml .\output.xsd .\src
它會創建一些文件:
.
\_src
\_com
\_project
\_xml
|_ObjectFactory.java
|_Output.java
然后,您可以在下面創建一些有用的方法來操作Output
對象:
private JAXBContext jaxbContext = null;
private Unmarshaller unmarshaller = null;
private Marshaller marshaller = null;
public OutputManager(String packageName) {
try {
jaxbContext = JAXBContext.newInstance(packageName);
unmarshaller = jaxbContext.createUnmarshaller();
marshaller = jaxbContext.createMarshaller();
} catch (JAXBException e) {
}
}
public Output loadXML(InputStream istrm) {
Output load = null;
try {
Object o = unmarshaller.unmarshal(istrm);
if (o != null) {
load = (Output) o;
}
} catch (JAXBException e) {
JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), e.getClass().getSimpleName(), JOptionPane.ERROR_MESSAGE);
}
return load;
}
public void saveXML(Object o, java.io.File file) {
Output save = null;
try {
save = (Output) o;
if (save != null) {
marshaller.marshal(save, file);
}
} catch (JAXBException e) {
JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), e.getClass().getSimpleName(), JOptionPane.ERROR_MESSAGE);
}
}
public void saveXML(Object o, FileOutputStream ostrm) {
Output save = null;
try {
save = (Output) o;
if (save != null) {
marshaller.marshal(save, ostrm);
}
} catch (JAXBException e) {
JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), e.getClass().getSimpleName(), JOptionPane.ERROR_MESSAGE);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.