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

JAXB - Make nested child element from Java object filed

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

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

然后在其他 class 中使用 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>

但实际上我希望它生成具有另一个层次结构的 XML - 我想从某些字段制作嵌套的 XML 标签,例如:

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

那么有什么方法可以做到这一点,而不必创建新的 Java classes 和 subclasses 吗?因为真正的代码比这长得多,而且有更多的字段,我不能从头开始重写..

我似乎有解决方案,但没有使用 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>