JAXB - 从Java对象字段创建嵌套的子元素

时间:2015-01-24 14:24:09

标签: java xml jaxb xml-serialization marshalling

我正在尝试通过JAXB从Java对象生成XML文件。我有以下Java类:

@XmlRootElement
public class StudentsInfo {

    String university;
    String faculty;
    long facultyNumber;
    int degree;
    String specialty;

    public String getUniversity() {
        return university;
    }
    @XmlElement
    public void setUniversity(String university) {
        this.university = university;
    }

    public String getFaculty() {
        return faculty;
    }
    @XmlElement
    public void setFaculty(String faculty) {
        this.faculty = faculty;
    }

    public long getFacultyNumber() {
        return facultyNumber;
    }
    @XmlElement
    public void setFacultyNumber(long facultyNumber) {
        this.facultyNumber = facultyNumber;
    }

    public int getDegree() {
        return degree;
    }
    @XmlElement
    public void setDegree(int degree) {
        this.degree = degree;
    }

    public String getSpecialty() {
        return specialty;
    }
    @XmlElement
    public void setSpecialty(String specialty) {
        this.specialty = specialty;
    }
}

然后在使用main()方法的其他类中,我这样做:

StudentsInfo studentsInfo = new StudentsInfo();
        studentsInfo.setFaculty("university name");
        studentsInfo.setFaculty("faculty name");
        studentsInfo.setFacultyNumber(1234);
        studentsInfo.setDegree(1);
        studentsInfo.setSpecialty("specialty name");

        // create an XML from studentsInfo
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(StudentsInfo.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            // output pretty printed
            jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            StringWriter sw = new StringWriter();
            jaxbMarshaller.marshal(studentsInfo, sw);
            String stringXML = sw.toString();
            System.out.println(stringXML);
        } catch (JAXBException e) { e.printStackTrace(); }

所以JAXB生成以下XML:



<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<studentsInfo>
    <degree>1</degree>
    <faculty>faculty name</faculty>
    <facultyNumber>1234</facultyNumber>
    <specialty>specialty name</specialty>
    <university>university name</university>
</studentsInfo>
&#13;
&#13;
&#13;

但实际上我希望它用另一个层次结构生成XML - 我想从某些字段中创建嵌套的XML标记,例如:

&#13;
&#13;
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<studentsInfo>
    <!-- I want to have some nested elements like these for example: -->
    <university name="university name">
        <faculty>faculty name</faculty>
        <facultyNumber>1234</facultyNumber>
        <specialty>specialty name</specialty>
    </university>

    <degree>1</degree>

</studentsInfo>
&#13;
&#13;
&#13;

有没有办法做到这一点,而不必创建新的Java类和子类?因为真正的代码比这长得多,并且有更多的字段,我不能从头开始重写它。

1 个答案:

答案 0 :(得分:1)

似乎我有一个解决方案,但没有使用JAXB。如果这不是一个选项,我会删除我的答案。当您使用数据投影而不是数据绑定时,例如XMLBeam(披露:我与该项目有关联),您可以将Java和XML结构解耦为:

public class CreateStudentsInfo {

public interface StudentsInfo{

    @XBWrite("/studentsInfo/university/@name")
    StudentsInfo setUniversityName(String universityName);

    @XBWrite("/studentsInfo/university/faculty")
    StudentsInfo setFacultyName(String facultyName);

    @XBWrite("/studentsInfo/university/facultyNumber")
    StudentsInfo setFacultyNumber(int facultyNumber);

    @XBWrite("/studentsInfo/university/specialty")
    StudentsInfo setSpecialty(String specialtyName);

    @XBWrite("/studentsInfo/degree")
    StudentsInfo setDegree(int degree);
}

public static void main(String[] args) {        
    StudentsInfo studentsInfo = new XBProjector(Flags.TO_STRING_RENDERS_XML).projectEmptyDocument(StudentsInfo.class);
    studentsInfo.setUniversityName("university name").setFacultyName("faculty name").setFacultyNumber(1234);
    studentsInfo.setSpecialty("speciality name").setDegree(1);
    System.out.println(studentsInfo);
 }
}

此程序打印出来:

<studentsInfo>
  <university name="university name">
    <faculty>faculty name</faculty>
    <facultyNumber>1234</facultyNumber>
    <specialty>speciality name</specialty>
  </university>
  <degree>1</degree>
</studentsInfo>