【问题标题】:Jaxb Complex Marshal elementJaxb 复杂元帅元素
【发布时间】:2011-08-28 08:41:32
【问题描述】:

我有一个复杂的 XML,我需要从中构建 java 对象。 我使用 Unmarshal 来做这件事。 虽然这项工作很完美,但我还需要将 Java 对象打印为字符串。 我有两个解决方案:

  1. 为每个嵌套类实现 toString() 方法。 -> 这很好用
  2. 执行元帅。 -> 这里有错误。

我有这个 XML:

<Lang>
        <a1 NAM="Momo" RTA="" />
        <a2 NAM="Rena" RTA="buba" />
        <a3 NAM="Fiba" RTA="kusit" />
        <a4 NAM="Shila" RTA="hamuda" />
<Lang>  

我需要生成 java 对象的地图表示。

Map - Key 是本例中的第一个属性 a1,a2,a3...

Map - value 是其余的属性 - 为此我实现了具有属性 NAM 和 RTA 的类,类名为 BBB。

在这个类中,我构建了一个具有 1 个参数 - 元素的构造函数。

我从 Unmarshall 方法调用这个构造函数

我现在不知道地图中值的数量。

我现在不知道属性的名称 - a1 , a2 .. 需要是通用的

所以,我为正确解组所做的工作是:

  1. 我构建了一个包含元素列表 (org.w3c.dom.Element) 的类 - 带有 @XmlAnyElement 注释。 类名是ABC

  2. 我建立了一个类来扩展 XmlAdapter{ABC, MAP{String,BBB}}

    并实现了 Unmarshall 方法,而不是实现 Marshall 方法

这很好用,我得到的数据完全符合我的预期。 现在我想实现 Marshal 方法,但不确定是否要这样做,因为 element 不是常规对象 - 它是一个接口。

元帅法:

@Override
public LangVos marshal(Map<String, BBB> map) {
    ABC abc = new ABC();
    langVos.langVOs = new ArrayList<Element>(map.size());
    for (Entry<String, BBB> entry : map.entrySet()) {

        Element e = (Element) entry.getValue(); // how to create Element using factory from entry ?
        ABC.list.add(e); 
    }
    return abc;
}

我现在不知道如何在 marshall 中设置属性。 在解组时,我需要执行 getAttribute。

我希望我说的很清楚。

感谢您的帮助。

鲍里斯。

【问题讨论】:

    标签: java jaxb marshalling element


    【解决方案1】:

    对于元帅,您应该能够通过创建包装 BBB 实例的 JAXBElements 来完成您需要的工作:

    package forum7219883;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import javax.xml.bind.JAXBElement;
    import javax.xml.bind.annotation.adapters.XmlAdapter;
    import javax.xml.namespace.QName;
    
    import org.w3c.dom.Element;
    
    public class MapAdapter extends XmlAdapter<AdaptedMap, Map<String, BBB>>{
    
        @Override
        public AdaptedMap marshal(Map<String, BBB> map) throws Exception {
            AdaptedMap adaptedMap = new AdaptedMap();
            for(Entry<String, BBB> entry : map.entrySet()) {
                adaptedMap.entry.add(new JAXBElement<BBB>(new QName(entry.getKey()), BBB.class, entry.getValue()));
            }
            return adaptedMap;
        }
    
        @Override
        public Map<String, BBB> unmarshal(AdaptedMap arg0) throws Exception {
            int entrySize = arg0.entry.size();
            Map<String, BBB> map = new HashMap<String, BBB>(entrySize);
            for(int x=0; x<entrySize; x++) {
                Element element = (Element) arg0.entry.get(x);
                BBB bbb = new BBB();
                bbb.setNam(element.getAttribute("NAM"));
                bbb.setRta(element.getAttribute("RTA"));
                map.put(element.getLocalName(), bbb);
            }
            return map;
        }
    
    }
    

    【讨论】:

    • 您好,感谢您的回复。当我执行 marshal 方法时,我得到 Exception : Caused by: javax.xml.bind.JAXBException: server.model.BBB is not known to this context 你能指教吗?谢谢!
    • @boris - 您只需在传入的类列表中包含 BBB 即可创建 JAXBContext。
    • 对不起,我该怎么做呢?元帅看起来像这样: StringWriter writer = new StringWriter(); Marshaller marshaller = jc.createMarshaller(); marshaller.marshal(响应,作家); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); System.out.println("来自马歇尔的回应" + writer.toString());
    • @boris - 我的意思是当你创建 JAXBContext 时:JAXBContext jc = JAXBContext.newInstance(LangVos.class, BBB.class);
    • 再次感谢。它仍然无法正常工作。现在我得到 NullPointerException : 引起:com.sun.xml.internal.bind.api.AccessorException: java.lang.NullPointerException at com.sun.xml.internal.bind.v2.runtime.reflect.AdaptedAccessor.get( Unknown Source) at com.sun.xml.internal.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(Unknown Source) ... 21 更多原因:java.lang.NullPointerException at model.adapter.mapAdapter.marshal(mapAdapter .java:48)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多