【问题标题】:Jaxb child attributes with same name mapping to parent object具有相同名称的 Jaxb 子属性映射到父对象
【发布时间】:2014-08-13 16:40:27
【问题描述】:

我有一个这种格式的 xml 文档:

<company>
    <employees>
        <employee firstname="xyz" lastname="abc">
            <empId ID="1"/>
            <department ID="D1"/>
            <manager ID="23"/>
        </employee>
    </employees>
    <departments>
        <department name="dept 1">
            <deptId ID="D1"/>
        </department>
    </departments>
 <company>

我正在尝试使用 JAXB 将其解组为 Java,但无法确定将员工 ID 映射到 Employee 类中的 id 字段的方法。

public class Employee{

@XmlAttribute
private String firstname;

@XmlAttribute
private String lastname;

???
@XmlID
private String id;

???
@XmlIDREF
private String managerId;

}

有什么建议吗?

【问题讨论】:

    标签: java xml jaxb


    【解决方案1】:

    根据一些评论反馈,您可以尝试使用以下方法编组数据:

    创建两个类来表示对象类中的 ID 字段:

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name="deptId")
    public class DepartmentId {
        @XmlAttribute(name="ID") // define an attribute for the ID
        @XmlID
        String id;
        @XmlValue  // define a value, and set to null
        String value = null;
    
        public DepartmentId() {}
    
        public void setId(String id) { this.id = id; }
        public String getId() { return this.id; }
    }
    

    和

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name="empId")
    public class EmployeeId {
        @XmlAttribute(name="ID")
        @XmlID
        String id;
        @XmlValue
        String value = null;
    
        public EmployeeId() {}
    
        public void setId(String id) { this.id = id; }
        public String getId() { return this.id; }
    } 
    

    像这样注释您的 Employee 类: 可能需要对您的 getter/setter 方法进行一些轻微的修改,这非常粗糙,但它应该可以与下面的测试一起使用,原样

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name="employee")
    public class Employee {
    
        @XmlElement(name="empId")
        private EmployeeId id; // an employee ID object will be used to represent this element
    
        @XmlAttribute(name="firstname")
        private String firstName;
    
        @XmlAttribute(name="lastname")
        private String lastName;
    
        @XmlElement(name="manager")
        private EmployeeId manager;  // same with the manager
    
        @XmlElement(name="department")
        private DepartmentId department;  // same with the dept
    
        public Employee() {
    
        }
    
        public void setId(String id) {
            this.id = new EmployeeId();
            this.id.setId(id);
        }
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
        public void setLastName(String lastName) {
            this.lastName = lastName;
        }
    
        public void setManager(Employee manager) {
            this.manager = new EmployeeId();
            this.manager.setId(manager.getId());
        }
    
        public void setDepartment(Department department) {
            this.department = new DepartmentId();
            this.department.setId(department.getId());
        }
    
        public String getId() { return this.id.getId(); }
        public String getFirstName() { return this.firstName; }
        public String getLastName() { return this.lastName; }
        public EmployeeId getManager() { return this.manager; }
        public DepartmentId getDepartment() { return this.department; }
    }
    

    Department 类注释如下:

    @XmlRootElement(name="department")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Department {
    
        @XmlElement(name="deptId")
        private DepartmentId id;
    
        public Department() {}
    
        public void setId(String id) {
            this.id = new DepartmentId();
            this.id.setId(id);
        }
        public String getId() { return this.id.getId(); }
    }
    

    Company 类注释如下:

    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Company {
    
        @XmlElement(name="employee")
        private List<Employee> employees;
    
        @XmlElement(name="department")
        private List<Department> departments;
    
        public Company() {
            employees = new ArrayList<Employee>();
            departments = new ArrayList<Department>();
        }
    
        public List<Employee> getEmployees() { return this.employees; }
        public void setEmployees(List<Employee> employees) { this.employees = employees; }
        public List<Department> getDepartments() { return this.departments; }
        public void setDepartments(List<Department> departments ) { this.departments = departments; }
    }
    

    通过以下测试:

    public class Test {
        public static void main(String[] args) throws Exception {
            Company c = new Company();
            Department d1 = new Department();
            d1.setId("D1");
            Department d2 = new Department();
            d2.setId("D2");
    
            Employee e1 = new Employee();
            e1.setId("1");
            e1.setFirstName("Joe");
            e1.setLastName("Smith");
            e1.setDepartment(d1);
    
            Employee e2 = new Employee();
            e2.setId("2");
            e2.setFirstName("John");
            e2.setLastName("Doe");
            e2.setManager(e1);
            e2.setDepartment(d1);
    
            c.getEmployees().add(e1);
            c.getEmployees().add(e2);
            c.getDepartments().add(d1);
            c.getDepartments().add(d2);
    
            JAXBContext context = JAXBContext.newInstance(Company.class);
            Marshaller m = context.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            m.marshal(c, System.out);
        }
    }
    

    生成以下 XML:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <company>
        <employee firstname="Joe" lastname="Smith">
            <empId ID="1"/>
            <department ID="D1"/>
        </employee>
        <employee firstname="John" lastname="Doe">
            <empId ID="2"/>
            <manager ID="1"/>
            <department ID="D1"/>
        </employee>
        <department>
            <deptId ID="D1"/>
        </department>
        <department>
            <deptId ID="D2"/>
        </department>
    </company>
    

    由于您有一个嵌入标签employees 和departments,您将需要另外几个类来处理该级别的嵌套。看看这是否适合你。

    请参阅this reference 和this reference 了解更多信息。

    【讨论】:

    • 感谢瑞恩的详细回复。但问题是我无法控制 xml 格式。它由第三方应用程序生成。我需要使用该数据进行进一步处理。
    • 一切都没有丢失,您只需要有几个额外的类来保存您需要的数据。查看我的编辑并试一试。
    • 再次感谢瑞恩。这可行,但需要注意的是,不能有外键。即,Employee 对象将包含一个 DepartmentID 键,该键与该部门的 DepartmentID 键不同。
    • 不确定我是否关注,但我很高兴听到您走得更远。如果我能提供进一步的帮助,请告诉我。
    • 我正在寻找的是类似于使用@XmlIDREF 来引用其他对象而不是创建 ID 的实例:stackoverflow.com/questions/15635318/… 即,Employee 应该包含一个 Department 类型的对象,而不是“DepartmentID”和另一个类型为“Employee”而不是“EmployeeID”的对象称为经理
    猜你喜欢
    • 2012-06-06
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    • 2016-01-04
    • 2017-02-28
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多