简体   繁体   English

如何在XStream或JAXB上将两个XML元素级别映射到一个级别?

[英]How to map two XML element levels to one level on XStream or JAXB?

I'm facing some difficulties to map two levels of XML elements to one level in my Java Bean. 我在将两层XML元素映射到Java Bean中的一层时遇到了一些困难。 Here is my context, I have one XML like this: 这是我的上下文,我有一个这样的XML:

<?xml version='1.0' encoding="utf-8" ?>
<Employee>
    <Data>
        <CompanyId>1</CompanyId>
        <FirstName>John</FirstName>
        <LastName>Oliver</LastName>
        <DOB>1986-21-07</DOB>
    </Data>
</Employee>

And here is my Java Bean: 这是我的Java Bean:

@XStreamAlias("Employee/Data")
public  class Employee {
    @XStreamAlias("CompanyId") private int companyId;
    @XStreamAlias("FirstName") private String firstName;
    @XStreamAlias("LastName")  private String lastName;
    @XStreamAlias("DOB")       private LocalDate birthDate;
    public int getCompanyId() { return companyId; }
    public void setCompanyId(int companyId) { this.companyId = companyId; }
    public String getFirstName() { return firstName; }
    public void setFirstName(String firstName) { this.firstName = firstName; }
    public String getLastName() { return lastName; }
    public void setLastName(String lastName) { this.lastName = lastName; }
    public LocalDate getBirthDate() { return birthDate; }
    public void setBirthDate(LocalDate birthDate) { this.birthDate = birthDate; }
}

I put the XML elements separated by "/" just to illustrate how I want to map, but it seems XStream does not work on this way. 我将XML元素用“ /”分隔,只是为了说明我要如何映射,但是XStream似乎无法以这种方式工作。 Any trick to map using annotations or should I write a custom converter? 使用注释映射的任何技巧还是应该编写自定义转换器? If someone knows how to do this mapping in JAXB is also welcome. 如果有人知道如何在JAXB中进行此映射,则也欢迎使用。

I found a solution using JAXB + eclipselink moxy. 我找到了使用JAXB + eclipselink moxy的解决方案。 First add the eclipselink dependency 'org.eclipse.persistence:org.eclipse.persistence.moxy:2.6.4' and to ensure you are using the eclipselink implementation in you application you need pass via command-line a JVM parameter 首先添加eclipselink依赖项'org.eclipse.persistence:org.eclipse.persistence.moxy:2.6.4'并确保您在应用程序中使用eclipselink实现,您需要通过命令行传递JVM参数

-Djavax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

or just set in you method main like I did: 或者像我一样在您的方法main中设置:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.time.LocalDate;
import java.time.Month;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

import org.eclipse.persistence.oxm.annotations.XmlPath;

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

    @XmlPath("Data/CompanyId/text()") private int companyId;
    @XmlPath("Data/FirstName/text()") private String firstName;
    @XmlPath("Data/LastName/text()")  private String lastName;
    @XmlPath("Data/DOB/text()")       private LocalDate birthDate;

    public int getCompanyId() { return companyId; }
    public void setCompanyId(int companyId) { this.companyId = companyId; }
    public String getFirstName() { return firstName; }
    public void setFirstName(String firstName) { this.firstName = firstName; }
    public String getLastName() { return lastName; }
    public void setLastName(String lastName) { this.lastName = lastName; }
    public LocalDate getBirthDate() { return birthDate; }
    public void setBirthDate(LocalDate birthDate) { this.birthDate = birthDate; }

    public String toString() {
        return String.format("{companyId: %d, firstName: \"%s\", lastName: \"%s\"}", companyId, firstName, lastName);
    }


    public static void main(String[] args) throws Exception {

        System.setProperty("javax.xml.bind.context.factory", "org.eclipse.persistence.jaxb.JAXBContextFactory");

        Employee employee = new Employee();
        employee.setCompanyId(100);
        employee.setFirstName("Michael");
        employee.setLastName("Hoffmann");
        employee.setBirthDate(LocalDate.of(1970,  Month.JANUARY, 19));

        JAXBContext jaxbContext = JAXBContext.newInstance(Employee.class);
        StringWriter sw = new StringWriter();
        PrintWriter out = new PrintWriter(sw);

        jaxbContext.createMarshaller().marshal(employee, out);
        out.flush();
        String xml = sw.toString();
        System.out.println(xml);

        InputStream in = new ByteArrayInputStream(xml.getBytes());


        Employee employee2 = (Employee) jaxbContext.createUnmarshaller().unmarshal(in);
        System.out.println(employee2);

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM