Jaxb不会捕获所有的子节点

时间:2012-05-10 09:38:39

标签: java jaxb

我有一个xml文档,看起来像这样

<root>
<subElement>
    <a>an instance</a>
    <b>another instance</b>
    <problemElement>
      <option>1st instance</option>
      <option>2nd instance</option>
      <option>3rd instance</option>
    </problemElement>

</subElement>

<subElement>
    <a></a>
    <b></b>
    <problemElement>
      <option>instance</option>
    </problemElement>

</subElement>
</root>

我的jaxb类看起来像这样;

@XmlRootElement(name = "root")
@XmlType(name = "Root")
public class Root{

  @XmlElement(name = "subElement", required = true)
  private final List<SubElement> subElementList = new ArrayList<SubElement>();

  public List<SubElement> getSubElementList() {
    return subElementList;
  }
}



@XmlType(name = "SubElement", propOrder = {"a", "b", "problemElement"})
public abstract class SubElement{

  @XmlElement(required = true)
  private String a;

  @XmlElement(required = true)
  private String b;

  @XmlElement(name = "problemElement", required = true)
  private List<ProblemElement> problemElement= new ArrayList<ProblemElement>();

  public String getA() {
    return a;
  }

  public String getB() {
    return b;
  }

  public List<ProblemElement> getProblemElement() {
    return problemElement;
  }
}



@XmlType(name = "ProblemElement" )
public class ProblemElement {

  @XmlElement(required = true)
  private String option;


  public String getOption() {
    return option;
  }
}

除了problemElement,一切正常。该列表仅返回xml中的最后一个选项节点值,在本例中为“3rd instance”。我究竟做错了什么?

2 个答案:

答案 0 :(得分:3)

简短回答

对于您的用例,我会利用@XmlElementWrapper属性上的problemElement注释:

@XmlElementWrapper(name="problemElement")
@XmlElement(name="option")
private List<ProblemElement> problemElement = new ArrayList<ProblemElement>();

我会在@XmlValue属性上使用option属性:

  @XmlValue
  private String option;

LONG ANSWER

下面是一个完全映射的示例。

<强>根

package forum10531285;

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

@XmlRootElement(name = "root")
@XmlType(name = "Root")
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlElement(name = "subElement", required = true)
    private final List<SubElement> subElementList = new ArrayList<SubElement>();

}

<强>子元素

package forum10531285;

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

@XmlType(name = "SubElement", propOrder = { "a", "b", "problemElement" })
@XmlAccessorType(XmlAccessType.FIELD)
public class SubElement {

    @XmlElement(required = true)
    private String a;

    @XmlElement(required = true)
    private String b;

    @XmlElementWrapper(name="problemElement")
    @XmlElement(name="option")
    private List<ProblemElement> problemElement = new ArrayList<ProblemElement>();

}

<强> ProblemElement

package forum10531285;

import javax.xml.bind.annotation.*;

@XmlType(name = "ProblemElement" )
@XmlAccessorType(XmlAccessType.FIELD)
public class ProblemElement {

  @XmlValue
  private String option;

}

<强>演示

package forum10531285;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum10531285/input.xml");
        Root root = (Root) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

<强> input.xml中/输出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <subElement>
        <a>an instance</a>
        <b>another instance</b>
        <problemElement>
            <option>1st instance</option>
            <option>2nd instance</option>
            <option>3rd instance</option>
        </problemElement>
    </subElement>
    <subElement>
        <a></a>
        <b></b>
        <problemElement>
            <option>instance</option>
        </problemElement>
    </subElement>
</root>

答案 1 :(得分:2)

抱歉,但是......你的问题元素可能有无限数量的选项?如果是这种情况,那么你应该编写代码而不是你的ProblemElement类:

public class ProblemElement {
    private List<String> options;

    public List<String> getOptions() {
        return options;
    }
    // other stuff here
}

否则您的JAXBinding将仅检索XML中的最后一个选项,在本例中为第3个选项。 当然,您应该相应地重写绑定注释。