使用JAXB使用XmlElement和XmlAttributes解析和XML

时间:2012-11-05 09:13:49

标签: xml jaxb xml-attribute

我无法使用JAXB解组下面的xml。请帮我解决这个问题。

我的xml看起来像这样:

   <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>

我正在尝试使用JAXB解组上面的xml。 以下是我的java课程:

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;
}

}

2 个答案:

答案 0 :(得分:3)

默认情况下JAXB (JSR-222)实现会查找属性上的元数据(get / set方法)。由于您已在PowerChanges类上注释了字段,因此需要使用@XmlAccessorType(XmlAccessType.FIELD)注释该类。我对您的PowerChanges课程进行了此更改,我能够完美地从您的帖子中读取XML。

解决方案 - 更改PowerChanges以使用字段访问

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;
    }
}

替代解决方案 - 在PowerChanges

上注释属性

或者,您可以将注释移动到get方法。

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;
    }
}

了解更多信息


你可能会得到一个例外,就像你当前的模型一样。在将来发布您看到的任何异常消息将帮助人们为您提供更好的答案。

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)

答案 1 :(得分:0)

您还可以设置XmlAccessType.NONE并注释要序列化的每个属性,编组只会考虑注释的那些。

属性powerChangeList应在getter或声明中注释。每个元素也应该使用自己的@XmlRootElement(name="element")进行注释。