2012-02-15 57 views
7

我在使用Marshaller.JAXB_FRAGMENT屬性成功編組時遇到了一些麻煩。這是我試圖輸出的XML的簡單版本。JAXB碎片編組

<Import> 
    <WorkSets> 
     <WorkSet> 
      <Work> 
      <Work> 
      ... 
      .. 
      ... 
     </WorkSet> 
     <WorkSet> 
      <Work> 
      <Work> 
      ... 
     </WorkSet> 
    <WorkSets> 
<Import> 

<Import><WorkSets>元件基本上圍住了大量的<WorkSet> & <Work>元件只是容器元素。我目前正在努力在<WorkSet>馬歇爾。

  1. 是否有可能最初封送<Import><WorkSets>元素,然後從此編組在<WorkSet>元件和具有輸出在<Import><WorkSets>標籤包圍?
  2. 當我在WorkSet級別進行封送處理時,它將xmlns='http://namespace.com'屬性附加到WorkSet標籤​​,是否有一種方法可以在沒有將名稱空間屬性附加到Workset的情況下編組?
+0

我不知道我理解你。什麼是「和元素」?我只看到WorkSet,WorkSets和Import。當你說「......最初把元素和元素組合起來,然後再從元素中釋放出來......」時,你的意思是什麼? – AlexR 2012-02-15 14:46:54

+0

@AlexR當我第一次發佈這個問題時,它並沒有在問題中顯示標籤,我對它進行了編輯,以便他們現在應該顯示,讓我知道如果他們不是。 – TyC 2012-02-15 14:48:33

+0

如果你已經接受了這篇文章中的答案,爲什麼你將問題重複爲[JAXB Fragment Marshal w/o namespace](http://stackoverflow.com/questions/9297872)?至少提到這個問題是分叉的...... – 2012-02-19 00:34:05

回答

17

基本上,聽起來像是用容器對象構建完整的對象樹,而您希望能夠使用JAXB將工作集實例的集合流式傳輸到元帥。

我會採取的方法是使用XMLStreamWriter並通過將工作集對象包裝到JAXBElement中來編組。我沒有測試示例代碼近在咫尺,所以這裏的粗糙的代碼段應該把你寫的軌道:

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<WorkSet> element = new JAXBElement<WorkSet>(QName.valueOf("WorkSet"), WorkSet.class, instance); 
    m.marshal(element, writer); 
} 

writer.writeEndDocument(); // this will close any open tags 
writer.close(); 

注:以上是完全未經測試,可能被搞亂的東西了在包裝部分編寫WorkSet的每個實例。您需要包裝WorkSet實例,因爲它們不會被註釋爲@XmlRootElement,否則JAXB將拒絕編組對象。

+0

謝謝@JörnHorstmann,我已經忘記了片段的一部分,只是回來添加它在我自己。 – Ophidian 2012-02-15 16:04:44

+1

謝謝!我只是試了一下,似乎運行良好。我添加了第二個問題,當WorkSet實例被編組時,出於某種原因xmlns屬性被附加到每個WorkSet元素,有沒有辦法在編組時將這個屬性賦值? – TyC 2012-02-15 16:14:15

+0

那我完全不確定。我想我會仔細閱讀JAXB javadocs。抱歉! – Ophidian 2012-02-16 13:29:47

0

另一種方法可能是將傳入的xml與創建根元素所需的元素進行包裝。然後獲取根元素的Java對象,並調用您正在查找的片段的getter。

舉例來說,如果你有這樣的XML:

<XmlRootElement> 
    <FragmentElement> 
     <foo>This is the foo value</foo> 
     <bar>This is the bar value</bar> 
    </FragmentElement> 
</XmlRootElement> 

你都交給這樣的:

<FragmentElement> 
    <foo>This is the foo value</foo> 
    <bar>This is the bar value</bar> 
</FragmentElement> 

您可以與XmlRootElement將標籤包裹的字符串,然後解析生成的字符串成根對象並從中獲取片段對象。例如:

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