1

有没有办法在 JAXB 中自定义 XML 序列化,就像在 .NET 中使用 IXmlSerializable 一样?(即使用等效的 XmlReader/Writer 直接控制对象序列化的能力)。

我已经查看了 XmlAdapter 和 @XmlJavaTypeAdapter,但它们似乎只是用于将类型转换为可序列化形式和从可序列化形式转换,这并不是我想要的。

更新:特别是,我想自定义根对象的反序列化,它以编程方式确定如何反序列化内部 XML(例如,创建具有一组特定已知类型的 jaxb 解组器)。

更新:我找到了解决问题的方法,但这是一个令人讨厌的 hack,我可能会采用其他海报建议的解决方案之一。

4

3 回答 3

6

好的,所以我设法让这个工作,虽然它是如此讨厌的解决方案,我想我会找到解决问题的更高级别的方法,正如 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); 
    }
}
于 2009-02-09T10:38:21.147 回答
1

我不确定我完全理解你的目标是什么,但也许你可以在你的根对象的无参数构造函数中以编程方式做你想做的事情,当对象被解组时,它将被调用来实例化对象。

于 2009-02-08T22:37:11.037 回答
1

听起来您希望根节点基于从根节点本身获得的某种属性或知识包含两组不同的 xml 节点/树。

我倾向于通过首先创建一个模式 (xsd) 然后生成 Java 源代码来使用 JAXB,我从不修改它。我只修改架构和再生。我意识到JAXB不能以其他方式使用,通过注释源,购买我不能那样说,因为我不使用它。如果您是架构...请继续阅读

考虑一下:http ://www.w3schools.com/Schema/schema_complex_indicators.asp

而不是切换解组器,只需包含两个 xml 定义。无论如何,它们都会被解析,您可以通过在根节点上检查的任何属性来改变程序控制流。

于 2009-02-08T23:08:22.477 回答