简体   繁体   English

JAXB-解组列表 <Property> 到地图 <String, Property> 在Java中

[英]JAXB - Unmarshalling List<Property> to Map<String, Property> in Java

I need to change List to Map in JAXB unmarshalling file. 我需要将列表更改为JAXB解组文件中的Map。

The xml file xml文件

<jrx:person>
    <jrx:ulement name="id" type="Integer" value="1"/>
    <jrx:ulement name="name" type="String" value="neps"/>
    </jrx:person>

The java classes, Java类,

@XmlRootElement(name = "person")
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

    @XmlElement(name = "ulement")
    private List<Property> props;
}

@XmlRootElement(name = "ulement")
@XmlAccessorType(XmlAccessType.FIELD)
public class Property {

    @XmlAttribute
    protected String name;

    @XmlAttribute
    private String type;

    @XmlAttribute
    private String value;
}

I have to change the class implementation to 我必须将类实现更改为

@XmlRootElement(name = "person")
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

    @XmlElement(name = "ulement")
    **private Map<String, Property> props;**
}

So that i ll be able to fetch the property using the keys quickly. 这样我就可以使用键快速获取属性。 Please suggest me some implementation to make it work. 请建议我一些实现使其工作的实现。


I have done the following changes but still the values are not mapped, 我做了以下更改,但仍未映射值,

The classes, 上课

@XmlRootElement(name = "person")
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

    @XmlJavaTypeAdapter(value = PropertyAdapter.class)
    private Map<String, Property> map;

}

public class PropertyAdapter extends XmlAdapter<Properties, Map<String, Property>> {

    @Override
    public Properties marshal(Map<String, Property> arg0) throws Exception {
        return null;
    }

    @Override
    public Map<String, Property> unmarshal(Properties p) throws Exception {
        Map<String, Property> map = new HashMap<String, Property>();
        for (Property entry : p.props) { 
            map.put(entry.name, entry);
        }
        return map;
    }

}

public class Properties {

    @XmlElement(name = "ulement")
    public List<Property> props;
}

But the values r Null at , 但是值r Null位于,

@XmlRootElement(name = "person")
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

    **@XmlJavaTypeAdapter(value = PropertyAdapter.class)
    private Map<String, Property> map;**

}

What exactly is missing over there. 那边到底缺少什么。

Usually, you would use @XmlJavaTypeAdapter and the XmlAdapter superclass on Person to transform your List into a Map and the opposite. 通常,您将在Person上使用@XmlJavaTypeAdapter和XmlAdapter超类将List转换为Map,反之亦然。

The problem is that XmlJavaTypeAdapter does not apply to XmlRootElement. 问题是XmlJavaTypeAdapter不适用于XmlRootElement。

I see two solution to your problem : 我看到了两种解决您的问题的方法:

1. Executing the adapter logic before marshalling and after unmarshalling. 1.在编组之前和拆组之后执行适配器逻辑。

@XmlRootElement(name = "person",namespace="yourNamespace")
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {
    @XmlElement(name ="ulement",namespace="yourNamespace")
    private List<Property> listProperty;

    public Person(AdaptedPerson p){
        this.listProperty = p.getMap().values();
    }

    //getters and setters
}


public class AdaptedPerson {

    private Map<String,Property> map;

    public AdaptedPerson(Person person){
        map = new HashMap<>();
        for(Property p : person.getListProperty()){
            map.put(p.getName(),p);
        } 
    }

    //getters and setters

}

Then each time you unmarshall a person : 然后,每次您解组一个人时:

AdaptedPerson ap = new AdaptedPerson(p);

And before you marshall an AdaptedPerson : 在编组适应者之前:

Person p = new Person(ap);

2. Implementing the map logic directly inside the Person class 2.直接在Person类内部实现映射逻辑

@XmlRootElement(name = "person",namespace="yourNamespace")
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

    @XmlTransient
    private Map<String,Property> map;

    @XmlElement(name ="ulement",namespace="yourNamespace")
    private List<Property> properties;

    public Property getProperty(String name){
        if(map == null) this.init();
        return map.get(name);
    }

    public Property addProperty(Property p){
        if(map == null) this.init();
        map.put(p.getName(),p);
        properties.remove(p);
        properties.add(p);
    }

    public Boolean removeProperty(Property p){
        if(map == null) this.init();
        map.remove(p.getName());
        return properties.remove(p);
    }

    //More methods if you need them.

    private void init(){
        if(properties == null) properties = new ArrayList<>();
        map = new HashMap<>();
        for(Property p : properties){
            map.put(p.getName(),p);
        } 
    }


}

The problem with this method is that for each method of Map you want to use, you will have to code a method that keeps the list updated. 这种方法的问题在于,对于您要使用的每种Map方法,您都必须编写一种方法来使列表保持更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM