2009-02-04 52 views
0

有沒有一種方法可以在JAXB中定製XML序列化,就像在.NET中使用IXmlSerializable一樣? (即使用XmlReader/Writer的等價物直接控制對象的序列化的能力)。JAXB中的定製序列化

我已經看過XmlAdapter和@XmlJavaTypeAdapter,但它們似乎只是用於將類型轉換爲可序列化表單,並且這不是我想要的。

更新:特別是,我想定製一個根對象的反序列化,它以編程方式確定如何反序列化內部XML(例如,創建一個具有一組特定已知類型的jaxb解組器)。

更新:我找到了解決這個問題的方法,但它是如此惡劣的破解,我可能會用其他海報提出的解決方案之一。

+1

你能給你想如何自定義序列化的一些信息呢?例如,您不希望XML標籤名稱與字段名稱相同。 – Nick 2009-02-08 03:36:13

回答

1

我不確定我完全理解你的目標是什麼,但是也許你可以在你的根對象的無參數構造函數中以編程方式做你想做的事情,當它被調用時它將被調用來實例化對象解組。

1

聽起來就像你想要一個根節點包含兩個不同的xml節點/樹的集合,這是基於從根節點本身獲得的某種屬性或知識。

我傾向於通過首先創建一個模式(xsd)然後生成我永遠不會修改的Java源代碼來使用JAXB。我只修改模式和regen。我意識到JAXB不能以其他方式使用,通過註釋來源,購買我不能用這種方式說話,因爲我不使用它。如果你的模式...上

閱讀試想一下:http://www.w3schools.com/Schema/schema_complex_indicators.asp

而不是切換解組,只包括XML定義。不管你怎麼看,他們都會得到解析,你可以通過你在根節點上檢查的任何屬性改變你的程序控制流。

+0

你釘住了我的問題 - 現場。絕對同意XSD,但我沒有將其標記爲已接受,因爲我認爲可能有辦法通過使用XmlAdapter來解決我的問題。我們拭目以待... – Andy 2009-02-09 09:50:48

3

好的,所以我設法做到了這一點,儘管這是一個非常糟糕的解決方案,我想我會找到解決這個問題的更高級別的方法,就像Fabian和basszero提到的那樣。下面的代碼的想法是爲要序列化的數據創建一個通用的可序列化引用,該引用維護一個JAXB java類型的適配器以編程方式執行序列化,還包含一個存儲結果XML的字符串字段。

注:代碼已經大大簡化了顯示...

// Create an instance of this class, to wrap up whatever you want to custom-serialize 
@XmlRootElement 
public static class SRef 
{ 
    public SRef() { } 
    public SRef(Object ref) 
    { 
     this.ref = ref; 
    } 

    @XmlJavaTypeAdapter(SRefAdapter.class) 
    public Object ref; 
} 

// This is the adapted class that is actually serialized 
public static class SRefData 
{ 
    // This is a hint field to inform the adapter how to deserialize the xmlData 
    @XmlAttribute 
    public String hint; 

    // This contains the custom-serialized object 
    @XmlElement 
    public String xmlData; 
} 

    // Converts an object to and from XML using a custom serialization routine 
public static class SRefAdapter extends XmlAdapter<SRefData, Object> 
{ 
    @Override 
    public SRefData marshal(Object value) throws Exception 
    { 
     if (value instanceof MyType) 
     { 
      SRefData data = new SRefData(); 
      data.xmlData = doSomeSpecificSerialization(value); 
      data.hint = "myType"; 
      return data; 
     } 
     throw new IllegalArgumentException("Can't serialize unknown object type " + value.getClass()); 
    } 

    @Override 
    public Object unmarshal(SRefData refData) throws Exception 
    { 
     if (refData.hint.equals("myType")) 
     { 
      return doSomeSpecificDeserialization(refData.xmlData); 
     } 
     throw new IllegalArgumentException("Unhandled hint value in SRefData: " + refData.hint); 
    } 
}