簡體   English   中英

JAXB更新XML元素

[英]JAXB update XML elements

我為需要創建和更新的JavaFX桌面應用程序獲取了兩個XML文件。 經過一番研究,我發現JAXB可以輕松完成這項工作。

現在閱讀可以正常工作,但是當我嘗試更新XML元素時,它將引發異常:

線程“主”中的異常java.io.FileNotFoundException:\\ storage \\ device.xml(系統找不到指定的路徑)

我也嘗試使用屬性文件,但是感覺與我需要的層次結構不對應。

JAXB是否不是更新XML文件中現有元素的方法,還是在這種情況下需要使用DOM解析器?

現在,我已經苦苦掙扎了數小時,沒有任何解決方案。 我使用Maven,XML文件存儲在資源文件夾內的存儲文件夾中。 有關更多信息,請參見下面的代碼示例。

歡迎提供解決此問題的所有反饋,建議或任何其他解決方案(其他存儲解決方案?)。

也許您知道一些更好的解決方案來處理這兩個XML文件?

先感謝您!

DeviceDemo.java

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class DeviceDemo {

    public static void main(String[] args) throws Exception {
        // Initialize
        String file = "/storage/device.xml";
        JAXBContext jaxbContext = JAXBContext.newInstance(Device.class);

        // Read
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        InputStream inputStream = DeviceDemo.class.getResourceAsStream(file);
        Device device = (Device) unmarshaller.unmarshal(inputStream);
        inputStream.close();

        // Update
        device.setName("Updated name");
        device.setHost("Updated host");
        device.setPort(2302);

        Marshaller marshaller = jaxbContext.createMarshaller();
        OutputStream outputStream = new FileOutputStream(file);
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(device, outputStream);
        outputStream.close();
    }

}

設備

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "device")
@XmlType(propOrder = {
        "name",
        "host",
        "port"
})
public class Device {

    private String name;
    private String host;
    private Integer port;

    public String getName() {
        return name;
    }

    @XmlElement(name = "name")
    public void setName(String name) {
        this.name = name;
    }

    public String getHost() {
        return host;
    }

    @XmlElement(name = "host")
    public void setHost(String host) {
        this.host = host;
    }

    public Integer getPort() {
        return port;
    }

    @XmlElement(name = "port")
    public void setPort(Integer port) {
        this.port = port;
    }

    @Override
    public String toString() {
        return name + " " + host + " " + port;
    }

}

Device.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<device>
    <name>Device</name>
    <host>host.com</host>
    <port>80</port>
</device>

CommandsDemo.java

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

public class CommandsDemo {

    public static void main(String[] args) throws Exception {
        // Initialize
        String file = "/storage/commands.xml";
        JAXBContext jaxbContext = JAXBContext.newInstance(Commands.class);

        // Read
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        InputStream inputStream = CommandsDemo.class.getResourceAsStream(file);
        Commands commands = (Commands) unmarshaller.unmarshal(inputStream);
        inputStream.close();

        // Print all commands
        List<Command> commandsList = commands.getCommands();

        for (Command command : commandsList) {
            System.out.println(command.toString());
        }

        // Update a specific command
        for (Command command : commandsList) {
            if (command.getName().equals("Power on")) {
                command.setName("Updated name");
                command.setHost("Updated host");
                command.setUser("Updated user");
                command.setPassword("Updated password");
                command.setTimeout(3439);
                command.setPort(33223);
                command.setCommand("Updated command");

                Marshaller marshaller = jaxbContext.createMarshaller();
                OutputStream outputStream = new FileOutputStream(file);
                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                marshaller.marshal(command, outputStream);
                outputStream.close();
            }
        }
    }

}

Commands.java

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;

@XmlRootElement(name = "commands")
public class Commands {

    private List<Command> commands;

    public List<Command> getCommands() {
        return commands;
    }

    @XmlElement(name = "command")
    public void setCommands(List<Command> commands) {
        this.commands = commands;
    }

    @Override
    public String toString() {
        return commands.toString();
    }

}

Command.java

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "command")
@XmlType(propOrder = {
        "name",
        "host",
        "user",
        "password",
        "port",
        "timeout",
        "command"
})
public class Command {

    private String name;
    private String host;
    private String user;
    private String password;
    private Integer port;
    private Integer timeout;
    private String command;

    public String getName() {
        return name;
    }

    @XmlElement(name = "name")
    public void setName(String name) {
        this.name = name;
    }

    public String getHost() {
        return host;
    }

    @XmlElement(name = "host")
    public void setHost(String host) {
        this.host = host;
    }

    public String getUser() {
        return user;
    }

    @XmlElement(name = "user")
    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return password;
    }

    @XmlElement(name = "password")
    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getPort() {
        return port;
    }

    @XmlElement(name = "port")
    public void setPort(Integer port) {
        this.port = port;
    }

    public Integer getTimeout() {
        return timeout;
    }

    @XmlElement(name = "timeout")
    public void setTimeout(Integer timeout) {
        this.timeout = timeout;
    }

    public String getCommand() {
        return command;
    }

    @XmlElement(name = "command")
    public void setCommand(String command) {
        this.command = command;
    }

    @Override
    public String toString() {
        return name + " " + host + " " + user + " " + password + " " + port + " " + timeout + " " + command;
    }

}

Commands.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<commands>
    <command>
        <name>Power on</name>
        <host>host.com</host>
        <user>user</user>
        <password>password</password>
        <port>22</port>
        <timeout>10000</timeout>
        <command>power on commando</command>
    </command>
    <command>
        <name>Power off</name>
        <host>host.com</host>
        <user>user</user>
        <password>password</password>
        <port>22</port>
        <timeout>10000</timeout>
        <command>power off command</command>
    </command>
</commands>

加載XML文件時,您正在使用getResourceAsStream 這將查找相對於類文件或當前目錄位置的文件/storage/device.xml 我現在不記得確切。

嘗試保存文件時,您使用的是具有相同名稱/storage/device.xml FileOutputStream 在這種情況下,它將相對於文件系統的根目錄。 如果那里沒有目錄/storage ,則系統將無法保存文件。

DeviceDemo示例

public class DeviceDemo {
    public static void main(String[] args) throws Exception {
        // Initialize
        // On unix this will result in the equivalent of $HOME/.powercontrol/storage/device.xml
        Path file = Paths.get(System.getProperty("user.home"), ".powercontrol", "storage", "device.xml");
        JAXBContext jaxbContext = JAXBContext.newInstance(Device.class);

        // Read
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        InputStream inputStream = new FileInputStream(file.toFile);
        Device device = (Device) unmarshaller.unmarshal(inputStream);
        inputStream.close();

        // Update
        device.setName("Updated name");
        device.setHost("Updated host");
        device.setPort(2302);

        // Write
        Marshaller marshaller = jaxbContext.createMarshaller();
        OutputStream outputStream = new FileOutputStream(file.toFile);
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(device, outputStream);
        outputStream.close();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM