JAXB碎片编组

我在使用Marshaller.JAXB_FRAGMENT属性成功编组时遇到了一些麻烦。 这是我想要输出的XML的简单版本。

     ... .. ...     ...    

元素本质上只是包含大量元素的容器元素。 我正在尝试在进行编组。

  1. 是否有可能最初编组元素,然后从元素的marshal编组,并将输出包含在标记中?
  2. 当我在WorkSet级别编组时,它将xmlns='http://namespace.com'属性xmlns='http://namespace.com'到WorkSet标记,有没有一种方法可以在没有将namespace属性附加到Workset的情况下编组?

基本上,它听起来不是使用容器对象构造完整的对象树,而是希望能够使用JAXB将一组WorkSet实例流式化为marshal。

我将采用的方法是使用XMLStreamWriter并通过将它们包装在JAXBElement中来封送WorkSet对象。 我手边没有经过测试的示例代码,所以这里有一个粗略的代码片段,可以让你在写入轨道上:

 FileOutputStream fos = new FileOutputStream("foo.xml"); XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(fos); writer.writeStartDocument(); writer.writeStartElement("Import"); writer.writeStartElement("WorkSets"); JAXBContext context = JAXBContext.newInstance(WorkSet.class); Marshaller m = context.createMarshaller(); m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); for (WorkSet instance : instances) { JAXBElement element = new JAXBElement(QName.valueOf("WorkSet"), WorkSet.class, instance); m.marshal(element, writer); } writer.writeEndDocument(); // this will close any open tags writer.close(); 

注意:以上内容是完全未经测试的,可能会在包装部分中弄乱一些东西来编写WorkSet的每个实例。 您需要包装WorkSet实例,因为它们不会使用@XmlRootElement进行注释,否则JAXB将拒绝@XmlRootElement对象。

另一种方法可能是使用创建根元素所需的元素包装传入的xml。 然后获取根元素的Java对象并为您要查找的片段调用getter。

例如,如果你有像这样的xml:

   This is the foo value This is the bar value   

你得到了这个:

  This is the foo value This is the bar value  

您可以使用XmlRootElement标记包装该字符串,然后将生成的字符串解析为根对象并从中获取片段对象。 就像是:

 public FragementElement getFragmentElement(String xml) { xml = "" + xml + ""; ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes()); JAXBElement obj = (JAXBElement) unmarshaller.unmarshal(is); XmlRootElement xmlRootElement = (XmlRootElement) obj.getValue(); FragementElement fragmentElement = xmlRootElement.getText(); return fragmentElement; }