Jaxb,Class有两个同名的属性

时间:2011-07-20 21:03:25

标签: java xml jaxb

使用jaxb,我尝试读取xml文件 只有xml文件中的一些元素很有趣,所以我想跳过很多元素

xml content

xml我尝试阅读

<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2010 rel. 3 sp1 (http://www.altova.com)-->
<flx:ModeleREP xsi:schemaLocation="urn:test:mod_rep.xsd mod_rep.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:flx="urn:test:mod_rep.xsd">
<flx:DocumentHeader>
    <flx:Identification v="04489"/>
</flx:DocumentHeader>
<flx:TimeSeries>
    <flx:Identification v="test1a"/>
    <flx:BusinessType v="A01"/>
    <flx:Product v="123a"/>
    <flx:ResourceObject codingScheme="N" v="testa"/>
    <flx:Period>
        <flx:TimeInterval v="2011-07-02T00:00/2011-07-16T00:00"/>
        <flx:Resolution v="PT2H"/>
        <flx:Pt>
            <flx:P v="1"/>
            <flx:Q unitCode="String" v="1.0"/>
            <flx:A currencyIdentifier="String" v="195.0"/>
        </flx:Pt>
    </flx:Period>
</flx:TimeSeries>
<flx:TimeSeries>
    <flx:Identification v="test2a"/>
    <flx:BusinessType v="A01"/>
    <flx:Product v="a123b"/>
    <flx:ResourceObject codingScheme="N" v="test2"/>
    <flx:Period>
        <flx:TimeInterval v="2011-07-02T00:00/2011-07-16T00:00"/>
        <flx:Resolution v="PT2H"/>
        <flx:Pt>
            <flx:P v="1"/>
            <flx:Q unitCode="String" v="1.0"/>
            <flx:A currencyIdentifier="String" v="195.0"/>
        </flx:Pt>
        <flx:Pt>
            <flx:P v="2"/>
            <flx:Q unitCode="String" v="1.0"/>
            <flx:A currencyIdentifier="String" v="195.0"/>
        </flx:Pt>
    </flx:Period>
</flx:TimeSeries>
</flx:ModeleREP>

我的班级

@XmlRootElement(name="ModeleREP", namespace="urn:test:mod_rep.xsd")
public class ModeleREP {

  @XmlElement(name="TimeSeries")
  protected List<TimeSeries> timeSeries;

  public List<TimeSeries> getTimeSeries() {
  if (this.timeSeries == null) {
      this.timeSeries = new ArrayList<TimeSeries>();
  }
  return this.timeSeries;
  }

  public void setTimeSeries(List<TimeSeries> timeSeries) {
  this.timeSeries = timeSeries;
  }

}

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

@XmlElement(name="ResourceObject")
protected RessourceObject resourceObject;

@XmlElement(name = "Period")
protected Period period;

public RessourceObject getResourceObject() {
    return this.resourceObject;
}

public void setResourceObject(RessourceObject resourceObject) {
    this.resourceObject = resourceObject;
}

public Period getPeriod() {
    return this.period;
}

public void setPeriod(Period period) {
    this.period = period;
}

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ResourceObject")

public class RessourceObject {
@XmlAttribute(name = "codingScheme")
protected String codingScheme;

@XmlAttribute(name = "v")
protected String v;

public String getCodingScheme() {
    return this.codingScheme;
}

public void setCodingScheme(String codingScheme) {
    this.codingScheme = codingScheme;
}

public String getV() {
    return this.v;
}

public void setV(String v) {
    this.v = v;
}
}

@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "Period")
public class Period {

@XmlElement(name = "TimeInterval")
protected TimeInterval timeInterval;

@XmlElement(name = "Pt")
protected List<Pt> pt;

public TimeInterval getTimeInterval() {
    return this.timeInterval;
}

public void setTimeInterval(TimeInterval timeInterval) {
    this.timeInterval = timeInterval;
}

public List<Pt> getPt() {
    if (this.pt == null) {
    this.pt = new ArrayList<Pt>();
    }
    return this.pt;
}

public void setPt(List<Pt> pt) {
    this.pt=pt;
}

}

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

@XmlAttribute(name = "v")
private String timeIntervalPeriod;

public String getTimeIntervalPeriod() {
    return this.timeIntervalPeriod;
}

public void setTimeIntervalPeriod(String timeIntervalPeriod) {
    this.timeIntervalPeriod = timeIntervalPeriod;
}

}

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

@XmlElement(name = "P")
protected P p;

@XmlElement(name = "A")
protected A a;

public P getP() {
    return this.p;
}

public void setP(P p) {
    this.p = p;
}

public A getA() {
    return this.a;
}

public void setA(A a) {
    this.a = a;
}
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "P")
public class P {
@XmlAttribute(name = "v")
protected String position;


public String getPosition(){
    return this.position;
}

public void setPosition(String position){
    this.position=position;
}
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "A")
public class A {
@XmlAttribute(name = "v")
protected String calculatedAmount;

public String getCalculatedAmount() {
    return this.calculatedAmount;
}

public void setCalculatedAmount(String calculatedAmount) {
    this.calculatedAmount = calculatedAmount;
}
}

当我尝试读取我得到的xlm文件时 我得到

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "timeSeries"
    this problem is related to the following location:
        at public java.util.List testjaxp.ModeleREP.getTimeSeries()
        at testjaxp.ModeleREP
    this problem is related to the following location:
        at protected java.util.List testjaxp.ModeleREP.timeSeries
        at testjaxp.ModeleREP

我不明白这个错误

编辑:我使用jaxb-impl-2.1.12

好吧现在我没有任何错误,但是当我检查我的对象时,timeSeries为空...

所以也许jaxb似乎对flx有问题?

19 个答案:

答案 0 :(得分:179)

我也遇到过像这样的问题,我设置了这个。

@XmlRootElement(name="yourRootElementName")
@XmlAccessorType(XmlAccessType.FIELD)

这将100%

答案 1 :(得分:22)

你没有指定你使用的是什么JAXB-IMPL版本,但是一旦遇到同样的问题(使用jaxb-impl 2.0.5)并使用getter级别的注释解决它而不是在成员处使用它水平。

答案 2 :(得分:21)

我也看到过类似的类似问题。

我认为,这是因为地方我们在其中使用“ @XMLElement 注释 (bean)class。

我认为, JAXB (注释处理器)会考虑成员字段&amp;当我们在字段级别使用 @XMLElement 注释并抛出 IllegalAnnotationExceptions 异常时,将相同字段元素的getter方法作为不同的属性。< / p>

异常消息:

  

类具有 相同 名称“timeSeries”的两个属性

Getter方法:

    at public java.util.List testjaxp.ModeleREP.getTimeSeries()

在会员现场:

    at protected java.util.List testjaxp.ModeleREP.timeSeries

解决方案: 不要在字段中使用 @XmlElement ,而是在 getter 方法中使用它。

答案 3 :(得分:11)

您的JAXB正在查看getTimeSeries()方法和成员timeSeries。您没有说明您正在使用哪个JAXB实现或其配置,但异常非常明确。

  

at public java.util.List testjaxp.ModeleREP.getTimeSeries()

  

at protected java.util.List testjaxp.ModeleREP.timeSeries

您需要配置JAXB内容以使用注释(根据您的@XmlElement(name="TimeSeries"))并忽略公共方法。

答案 4 :(得分:9)

刚刚把它添加到我的班级

@XmlAccessorType(XmlAccessType.FIELD)

像cham一样工作

答案 5 :(得分:7)

如果我们使用下面的注释并删除&#34; @ XmlElement&#34;注释,代码应该正常工作,结果XML的元素名称类似于类成员。

@XmlRootElement(name="<RootElementName>")
@XmlAccessorType(XmlAccessType.FIELD)

如果使用&#34; @ XmlElement&#34;确实是必需的,请将其定义为字段级别,代码应该完美。不要在getter方法的顶部定义注释。

已经尝试了上述两种方法并解决了这个问题。

答案 6 :(得分:7)

您需要像使用ModeleREP课一样使用@XmlAccessorType(XmlAccessType.FIELD)配置课程TimeSeries

请看OOXS

答案 7 :(得分:6)

有多种解决方案,但基本上,如果您对变量声明进行注释,则需要@XmlAccessorType(XmlAccessType.FIELD),但如果您希望对get方法或set方法进行注释,则不需要。

因此您可以这样做:

@XmlRootElement(name="MY_CLASS_A")
@XmlAccessorType(XmlAccessType.FIELD)
public class MyClassA
{
    @XmlElement(name = "STATUS")   
    private int status;
   //.. and so on
}

或者:

@XmlRootElement(name="MY_CLASS_A")
public class MyClassA
{
    private int status;

    @XmlElement(name = "STATUS")         
    public int getStatus()
    {
    }
}

答案 8 :(得分:5)

这些是JAXB正在关注的两个属性。

public java.util.List testjaxp.ModeleREP.getTimeSeries()  

protected java.util.List testjaxp.ModeleREP.timeSeries

这可以通过在get方法中使用JAXB注释来避免,如下所述。

@XmlElement(name="TimeSeries"))  
public java.util.List testjaxp.ModeleREP.getTimeSeries()

答案 9 :(得分:4)

只需在要转换为XML的类中将成员变量声明为private。 快乐的编码

答案 10 :(得分:4)

&#34; Class有两个同名属性的属性&#34; 可能会在您拥有具有公共访问级别和getter的类成员x时发生/ setter为同一成员。

作为java经验法则,建议不要将公共访问级别与getter和setter一起使用。

检查以获取更多详细信息: Public property VS Private property with getter?

解决这个问题:

  1. 将您的会员访问级别更改为私人并保留您的getter / setter
  2. 删除会员的getter和setter

答案 11 :(得分:2)

我刚遇到这个问题并解决了它。

问题的根源在于您同时拥有XmlAccessType.FIELD和一对getter和setter。解决方案是删除setter并添加一个默认构造函数和一个包含所有字段的构造函数。

答案 12 :(得分:2)

我遇到同样的问题,我补充说

@XmlRootElement(name="yourRootElementName")

@XmlAccessorType(XmlAccessType.FIELD)

现在它正在运作。

答案 13 :(得分:1)

当您将注释放在getter之前,并将其从受保护的属性中删除时,它将起作用:

protected String codingScheme;

@XmlAttribute(name = "codingScheme")
public String getCodingScheme() {
    return this.codingScheme;
}

答案 14 :(得分:1)

ModeleREP#getTimeSeries()必须带有@Transient批注。那会有所帮助。

答案 15 :(得分:0)

使用@XmlTransient进行注释可解决该问题

@XmlTransient
public void setTimeSeries(List<TimeSeries> timeSeries) {
   this.timeSeries = timeSeries;
}

查看http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/XmlTransient.html了解更多详情

答案 16 :(得分:0)

解决此问题的一种快速而简单的方法是从变量声明语句protected List<TimeSeries> timeSeries;的顶部删除public List<TimeSeries> getTimeSeries()到其getter的顶部ModeleREP

因此,您的@XmlRootElement(name="ModeleREP", namespace="urn:test:mod_rep.xsd") public class ModeleREP { protected List<TimeSeries> timeSeries; @XmlElement(name="TimeSeries") public List<TimeSeries> getTimeSeries() { if (this.timeSeries == null) { this.timeSeries = new ArrayList<TimeSeries>(); } return this.timeSeries; } public void setTimeSeries(List<TimeSeries> timeSeries) { this.timeSeries = timeSeries; } } 课程将如下所示:

AutoCompleteTextView

希望它有所帮助!

答案 17 :(得分:0)

我进行了反复试验,得出的结论是,您只需要同时使用@XMLElement@XmlAccessorType(XmlAccessType.FIELD)之一。

何时使用哪个?

情况1 :如果您要在xml文件中使用的字段名称和元素名称不同,则必须使用@XMLElement(name="elementName")。因为这将绑定具有该元素名称的字段并显示在XML文件中。

情况2 :如果xml中的字段名称和相应的元素名称都相同,那么您可以简单地使用@XmlAccessorType(XmlAccessType.FIELD)

答案 18 :(得分:0)

已经给出了许多解决方案,@Sriram和@ptomli也短暂地触及了内部。我只想添加一些对源代码的引用,以帮助了解幕后发生的事情。

默认情况下(除了根类上的 \w*(ai)\w* /m 以外,根本没有使用任何额外的注释),JABX尝试封送通过两种方式公开的内容:

  1. 公共fields
  2. getter methods,其后跟convention并具有相应的setter方法。

请注意,如果字段为@XmlRootElement(或方法返回),则不会将其写入输出。

现在,如果使用null,则也可以将非公共事物(可能是字段或getter方法)编组。

但是,两种方法(即字段和获取方法)一定不能相互冲突。否则,您会得到the exception