来自现有 XML 的 JAXB add/remove 节点

JAXB add/remove node from existing XML

我有以下代码来创建 XML 并通读它, 我想要实现的是,根据其 ID 删除特定节点。

Class employee.java -

package com.howtodoinjava.jaxb.examples.list;

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

@XmlRootElement(name = "employee")
@XmlAccessorType (XmlAccessType.FIELD)
public class Employee 
{
    private Integer id;
    private String firstName;
    private String lastName;
    private double income;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    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 double getIncome() {
        return income;
    }
    public void setIncome(double income) {
        this.income = income;
    }
}

Class Employees.java -

package com.howtodoinjava.jaxb.examples.list;

import java.util.List;

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

@XmlRootElement(name = "employees")
@XmlAccessorType (XmlAccessType.FIELD)
public class Employees 
{
    @XmlElement(name="employee")
    private List<Employee> employees = null;

    private Integer size;

    public List<Employee> getEmployees() {
        return employees;
    }
    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }
    public Integer getSize() {
        return size;
    }
    public void setSize(Integer size) {
        this.size = size;
    }
}

Class TestEmployeeMarshing.java -

package com.howtodoinjava.jaxb.examples.list;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class TestEmployeeMarshing 
{
    static Employees employees = new Employees();
    static 
    {
        employees.setEmployees(new ArrayList<Employee>());

        Employee emp1 = new Employee();
        emp1.setId(1);
        emp1.setFirstName("John");
        emp1.setLastName("Doe");
        emp1.setIncome(10000.0);

        Employee emp2 = new Employee();
        emp2.setId(2);
        emp2.setFirstName("Jane");
        emp2.setLastName("Doe");
        emp2.setIncome(20000.0);

        Employee emp3 = new Employee();
        emp3.setId(3);
        emp3.setFirstName("Bacon");
        emp3.setLastName("Butter");
        emp3.setIncome(30000.0);

        Employee emp4 = new Employee();
        emp4.setId(4);
        emp4.setFirstName("Pepparoni");
        emp4.setLastName("Pizza");
        emp4.setIncome(40000.0);

        employees.getEmployees().add(emp1);
        employees.getEmployees().add(emp2);
        employees.getEmployees().add(emp3);
        employees.getEmployees().add(emp4);
    }

    public static void main(String[] args) throws JAXBException 
    {
        marshalingExample();
        System.out.println("************************************************");
        unMarshalingExample();
    }

    private static void unMarshalingExample() throws JAXBException {

        JAXBContext jaxbContext = JAXBContext.newInstance(Employees.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        employees = new Employees();
        employees = (Employees) jaxbUnmarshaller.unmarshal( new File("G:/xml/employees.xml") );
        List<Employee> tempEmp=   employees.getEmployees();


        for (int i = 0; i < tempEmp.size(); i++) {

            if(tempEmp.get(i).getId().equals(3)){
                System.out.println("ID equals 3");
                tempEmp.remove(i);
            }
        }

        marshalingExample();

    }

    private static void marshalingExample() throws JAXBException
    {
        JAXBContext jaxbContext = JAXBContext.newInstance(Employees.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        jaxbMarshaller.marshal(employees, System.out);
        jaxbMarshaller.marshal(employees, new File("G:/xml/employees.xml"));
    }
}

我需要删除 ID 为 1 的节点并添加一个新节点。

您最好将读取数据的代码与使用它的代码分开,例如通过将代码的各个部分放在不同的方法中。此外,将数据传递给编组方法会更方便,以便更容易重用,而不是依赖 static employees 字段来传递数据。

Employees 实例中的 List 可以像任何其他可修改的实例一样进行修改 List:

private static Employees unmarshalFromFile(String fileName) throws JAXBException {
    JAXBContext jaxbContext = JAXBContext.newInstance(Employees.class);
    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    return (Employees) jaxbUnmarshaller.unmarshal(new File(fileName));
}

private static void marshalToFile(Employees data, String fileName) throws JAXBException
{
    JAXBContext jaxbContext = JAXBContext.newInstance(Employees.class);
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    jaxbMarshaller.marshal(data, new File(fileName));
}

public static void main(String[] args) throws JAXBException {
    Employees data = unmarshalFromFile("G:/xml/employees.xml");

    Integer removeId = 1;
    data.getEmployees().removeIf((Employee emp) -> removeId.equals(emp.getId()));

    Employee newEmployee = ...
    data.getEmployees().add(newEmployee);

    marshalToFile(data, "G:/xml/employees.xml");
}

removeIf 是在 java 8 中添加的,但您也可以在早期版本中通过遍历列表来执行此操作:

Iterator<Employee> iterator = data.getEmployees().iterator();
while (iterator.hasNext()) {
    if (removeId.equals(iterator.next().getId())) {
         iterator.remove();
    }
}