Domanda

I am unable to unmarshall the below xml using JAXB. Kindly help me to solve this.

My xml looks like this:

   <powerchanges>
     <initialState creationTime="14.08.2012 16:24:01" status="poweredOff" /> 
     <powerchange changeTime="14.08.2012 16:24:49" status="Powered On" /> 
     <powerchange changeTime="27.09.2012 02:17:23" status="Powered Off" /> 
     <powerchange changeTime="27.09.2012 02:51:13" status="Powered On" /> 
     <powerchange changeTime="29.09.2012 05:06:48" status="Powered Off" /> 
     <powerchange changeTime="29.09.2012 07:40:24" status="Powered On" />   
   </powerchanges>

I am trying to unmarshall the above xml using JAXB. Below are my java classes:

PowerChanges.java

@XmlRootElement(name="powerchanges")
public class PowerChanges {
@XmlElement(name = "initialState")
private InitialState initialState;

@XmlElement(name = "powerchange")
private ArrayList<PowerChange> powerChangeList;


public InitialState getInitialState() {
    return initialState;
}
public void setInitialState(InitialState initialState) {
    this.initialState = initialState;
}

public ArrayList<PowerChange> getPowerChangeList() {
    return powerChangeList;
}
public void setPowerChangeList(ArrayList<PowerChange> powerChangeList) {
    this.powerChangeList = powerChangeList;
}

}

PowerChange.java:

public class PowerChange {

  private String changeTime;
  private String status;

  @XmlAttribute
public String getChangeTime() {
    return changeTime;
}
public void setChangeTime(String changeTime) {
this.changeTime = changeTime;
}
@XmlAttribute
public String getStatus() {
return status;
}
public void setStatus(String status) {
    this.status = status;
}

} 

InitialState.java

public class InitialState {

  private String creationTime;
  private String status;

  @XmlAttribute
public String getCreationTime() {
    return creationTime;
}
public void setCreationTime(String creationTime) {
    this.creationTime = creationTime;
}
@XmlAttribute
public String getStatus() {
    return status;
}
public void setStatus(String status) {
    this.status = status;
}

}

È stato utile?

Soluzione

By default JAXB (JSR-222) implementations look for metadata on properties (get/set methods). Since you have annotated the fields on the PowerChanges class you need annotate the class with @XmlAccessorType(XmlAccessType.FIELD). I made this change to your PowerChanges class and I was able to read the XML from your post perfectly.

SOLUTION - Change PowerChanges to use Field Access

import java.util.ArrayList;
import javax.xml.bind.annotation.*;

@XmlRootElement(name = "powerchanges")
@XmlAccessorType(XmlAccessType.FIELD)
public class PowerChanges {
    @XmlElement(name = "initialState")
    private InitialState initialState;

    @XmlElement(name = "powerchange")
    private ArrayList<PowerChange> powerChangeList;

    public InitialState getInitialState() {
        return initialState;
    }

    public void setInitialState(InitialState initialState) {
        this.initialState = initialState;
    }

    public ArrayList<PowerChange> getPowerChangeList() {
        return powerChangeList;
    }

    public void setPowerChangeList(ArrayList<PowerChange> powerChangeList) {
        this.powerChangeList = powerChangeList;
    }
}

ALTERNATIVE SOLUTION - Annotate the Properties on PowerChanges

Alternatively you could move the annotations to the get methods.

import java.util.ArrayList;
import javax.xml.bind.annotation.*;

@XmlRootElement(name = "powerchanges")
public class PowerChanges {
    private InitialState initialState;

    private ArrayList<PowerChange> powerChangeList;

    @XmlElement(name = "initialState")
    public InitialState getInitialState() {
        return initialState;
    }

    public void setInitialState(InitialState initialState) {
        this.initialState = initialState;
    }

    @XmlElement(name = "powerchange")
    public ArrayList<PowerChange> getPowerChangeList() {
        return powerChangeList;
    }

    public void setPowerChangeList(ArrayList<PowerChange> powerChangeList) {
        this.powerChangeList = powerChangeList;
    }
}

For More Information


You were probably getting an exception very much like the following with your current model. In the future posting any exception messages you are seeing will help people provide you with better answers.

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
Class has two properties of the same name "initialState"
    this problem is related to the following location:
        at public forum13229013.InitialState forum13229013.PowerChanges.getInitialState()
        at forum13229013.PowerChanges
    this problem is related to the following location:
        at private forum13229013.InitialState forum13229013.PowerChanges.initialState
        at forum13229013.PowerChanges
Class has two properties of the same name "powerChangeList"
    this problem is related to the following location:
        at public java.util.ArrayList forum13229013.PowerChanges.getPowerChangeList()
        at forum13229013.PowerChanges
    this problem is related to the following location:
        at private java.util.ArrayList forum13229013.PowerChanges.powerChangeList
        at forum13229013.PowerChanges

    at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:451)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:283)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:126)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1148)
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:130)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:248)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:235)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:445)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:637)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
    at forum13229013.Demo.main(Demo.java:12)

Altri suggerimenti

You can also set XmlAccessType.NONE and annotate each attribute you want to serialize, the marshaller only considers those annotated.

The attribute powerChangeList should be annotated in the getter or in the declaration. Each element should be also annotated with its own @XmlRootElement(name="element").

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top