2013-01-08 66 views
4

我有兩個XML文件JAXB出口到模塊化的XML文件與十一:包括

tree.xml

<tree> 
    <xi:include href="fruit.xml" xmlns:xi="http://www.w3.org/2001/XInclude"> 
     <xi:fallback> 
      <fruit/> 
     </xi:fallback> 
    </xi:include> 
</tree> 

fruit.xml

<fruit> 
    ... 
</fruit> 

我繼承的代碼來解讀文件,並且它返回一個單獨的java對象。我現在需要將單個Java對象編組回到兩個文件。我意識到還有其他的解決方案(即使用兩個對象而不是一個,這是一個選項),但我需要知道是否可以編組單個對象並維護xi:include(或者重新引入它)並將其導出爲兩個(或更多)xml文件。

這甚至可能嗎?如果有的話,任何提示/想法?

感謝

更新:

我一直在研究這個(我之前問研究)。我確實發現這個教程http://tutorial.waycoolsearch.com/java/jaxb2.php似乎有我的答案,但唉,當我編組文件,它需要什麼是兩個,使一個。

回答

0

我想出了一個答案,至少有一項工作。我想這可能是做到這一點的方法。

我一直希望JAXB有一種方法來定義一個對象的一部分作爲編組包含,但我永遠找不到任何東西。

注:我有一個額外的黑客,我會在下面解釋,我想你可以做到這一點,但我無法得到它的工作,並在其他人需要這樣做的情況下,至少他們會知道。

流程如下。

  1. XI:Include的一個XML文件被解組到Java對象。該對象包含2個文件(父代和包含)的內容。
  2. 對象已更新。
  3. 該對象編組回到單個臨時文件(這是黑客)。
  4. 單個臨時文件被解析爲DOM文檔。 (我想直接編寫一個DOM文檔,但我總是得到一個空的DOM文檔,沒有例外)。
  5. 然後,我通過首先刪除需要進入XI:節點的節點,然後插入新的XI:include文件來操作DOM文檔。
  6. 將DOM文檔轉換爲xml文件。請注意,就我而言,XI:include的內容不會改變,但我認爲該節點可以放入新文檔並進行轉換。

我會盡快用代碼更新。

任何其他解決方法?

感謝, 特拉維斯

3

下面我將演示一個XmlAdapter是如何被用來支持和解組用於該用途的情況。

XmlAdapter(IncludeFruitAdapter)

一種XmlAdapter可以用於這種使用情況。

import java.io.File; 
import javax.xml.bind.*; 
import javax.xml.bind.annotation.*; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 

public class IncludeFruitAdapter extends XmlAdapter<IncludeFruitAdapter.Include, Fruit> { 

    private JAXBContext jc; 
    private String href = "fruit.xml"; 

    public IncludeFruitAdapter() { 
     try { 
      jc = JAXBContext.newInstance(Fruit.class); 
     } catch(Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 


    public static class Include { 

     @XmlAttribute 
     public String href; 

     @XmlElement(namespace="http://www.w3.org/2001/XInclude") 
     public Fallback fallback; 

    } 

    public static class Fallback { 

     @XmlElementRef 
     public Fruit value; 

    } 

    @Override 
    public Include marshal(Fruit fruit) throws Exception { 
     File xml = new File(href); 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(fruit, xml); 

     Include include = new Include(); 
     include.href = href; 
     include.fallback = new Fallback(); 
     include.fallback.value = new Fruit(); 
     return include; 
    } 

    @Override 
    public Fruit unmarshal(Include include) throws Exception { 
     File xml = new File(include.href); 
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     try { 
      return (Fruit) unmarshaller.unmarshal(xml); 
     } catch(Exception e) { 
      return include.fallback.value; 
     } 
    } 

} 

@XmlJavaTypeAdapter被用於引用XmlAdapter

import javax.xml.bind.annotation.*; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Tree { 

    @XmlJavaTypeAdapter(IncludeFruitAdapter.class) 
    @XmlElement(name="include", namespace="http://www.w3.org/2001/XInclude") 
    private Fruit fruit; 

} 

水果

import javax.xml.bind.annotation.*; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Fruit { 

    private String name; 

} 

演示

下面是一些演示代碼可以運行來證明一切正常:

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Tree.class); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     File xml = new File("input.xml"); 
     Tree tree = (Tree) unmarshaller.unmarshal(xml); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(tree, System.out); 

    } 

}