JAXB将多个XML元素解组为单个类
我有以下XML结构,它跨多个XML元素建模单个概念。 这种格式不在我的掌控之中。
1 x 2 y 1 Channel name 2 Another channel name
我想在我可以控制的数据库中对此进行建模,并且可以使用包含id
, type
和name
字段的更简单的Channel
表。 因此,我想在Wrapper
类的单个List
解组。
可以自动使用@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 channels;
对于更高级的情况,您可以在EclipseLink JAXB(MOXy)中使用@XmlPath扩展:
这是我到目前为止所拥有的。 我仍然试图消除对辅助对象的需求。 此示例需要EclipseLink JAXB(MOXy) 。
模型对象
您的模型对象是:
package example; import java.util.ArrayList; import java.util.List; public class Wrapper { private List channels = new ArrayList (); public List getChannels() { return channels; } public void setChannels(List 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 channelNames; @XmlTransient public Wrapper getWrapper() { for(ChannelName channelName : channelNames) { channelName.getChannel().setName(channelName.getName()); } return wrapper; } @XmlElementWrapper(name="Wrapper") @XmlElement(name="Channel") public List getChannels() { return wrapper.getChannels(); } public void setChannels(List channels) { wrapper.setChannels(channels); } @XmlElementWrapper(name="Wrapper") @XmlElement(name="ChannelName") public List getChannelNames() { return channelNames; } public void setChannelNames(List 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); } }