2015-08-22 5 views
0

У меня есть два файла XML для рабочего стола JavaFX, которые необходимо создать и обновить. После некоторых исследований я нашел JAXB простым парсером для этой работы.JAXB update XML-элементы

Сейчас читает отлично работает, но когда я пытаюсь обновить XML-элементы, он бросает исключение:

Исключение в потоке «главный» java.io.FileNotFoundException: \ хранение \ 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> 

ответ

1

При загрузке файла XML вы используете getResourceAsStream. Это будет искать ваш файл /storage/device.xml относительно местоположения вашего файла класса или, возможно, текущего каталога. Я точно не помню.

При попытке сохранить файл вы используете FileOutputStream с тем же именем, /storage/device.xml. В этом случае он будет относиться к корню вашей файловой системы. Если у вас нет каталога /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(); 
    } 
} 
+0

Это ясно, спасибо! Насколько мне известно, используется 'getResourceAsStream' базовый каталог. В любом случае, как я могу это решить, так что iit сможет редактировать существующий файл XML? – nberlijn

+0

Где именно находится ваш файл? Если он находится в текущем каталоге, используйте 'FileInputStream (« device.xml »)' при загрузке и использовании 'FileOutputStream (« device.xml »)' при сохранении. Или новое имя, если вы не хотите перезаписывать старый файл. Если файл находится в каталоге 'storage' в вашем текущем каталоге, используйте' 'storage/device.xml' 'в обоих случаях. –

+0

Я создал папку «storage» (с XML-файлами внутри) внутри папки «resources» (проект на основе Maven). Я застрял в этой части. – nberlijn