java - XML JAXB 编码未保存到 xml 文件

标签 java xml javafx java-8 jaxb

我有一个javafx程序,它会弹出一个文件选择器,允许用户选择和成像并将其显示到 GridView 中,并在选择图像后弹出插入的标题。我将文件路径和标题保存到不同的数组列表中(目前),我的目标是将两者保存到 xml 文件中,以便在重新打开应用程序时可以解码它,以便图像仍然存在。现在我只想能够将两个字符串保存到一个 xml 文件中,然后再弄清楚其余的内容。目前,我可以毫无错误地运行我的代码,直到达到我的 stop 方法,在该方法中我尝试保存用户添加到数组列表中的每个图像和标题。

我的 JAXB 注释:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ImageCap {
    private String filePath;
    private String caption;

    public ImageCap() {
    }

    public ImageCap(String filePath, String caption) {
        this.filePath = filePath;
        this.caption = caption;
    }

    @Override
    public String toString() {
        return "ImageCap{" + "filePath=" + filePath + ", caption=" + caption + '}';
    }

    public String getFilePath() {
        return filePath;
    }

    @XmlElement
        public void setFilePath(String filePath) {
            this.filePath = filePath;
        }

      public String getCaptions() {
            return caption;
        }

      @XmlElement
        public void setCaption(String caption) {
            this.caption = caption;
        }

    }

我的主要测试:

public static void main(String[] args) {launch(args);}

  public void start(Stage primaryStage) throws JAXBException{

  final JFXPanel bananarama = new JFXPanel();

  //import the library (read))

  // create the (initial) display
  display.makeBrowseButton(primaryStage);
  display.createDisplay(primaryStage);

  // show user
  primaryStage.show();



}@Override
public void stop() throws JAXBException{
  File file = new File("file.xml");
  JAXBContext jaxbContext = JAXBContext.newInstance(ImageCap.class);
  Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

//this.context = JAXBContext.newInstance(ImageCap.class);
  //Marshaller marshaller = context.createMarshaller();
  for(int i = 0; i < display.filePaths.size(); i++)
{
  ImageCap imageCap = new ImageCap();

   imageCap.setFilePath(display.filePaths.get(i));
   imageCap.setCaption(display.captions.get(i).toString());

System.out.println(display.filePaths.get(i).toString());
   try {

   // output pretty printed
   jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

   jaxbMarshaller.marshal(imageCap, file);


       } catch (JAXBException e) {
   e.printStackTrace();
       }

  }
}



以下是停止命令后我的错误:

    this problem is related to the following location:
        at public void ImageCap.setCaption(java.lang.String)
        at ImageCap
    this problem is related to the following location:
        at private java.lang.String ImageCap.caption
        at ImageCap
    Class has two properties of the same name "filePath"
    this problem is related to the following location:
        at public java.lang.String ImageCap.getFilePath()
        at ImageCap
    this problem is related to the following location:
        at private java.lang.String ImageCap.filePath
        at ImageCap

但它特别在第 81 行处中断,即: JAXBContext jaxbContext = JAXBContext.newInstance(ImageCap.class);

有什么想法吗?

最佳答案

如果您有同名字段的 getter 和 setter,那么您需要使用 XmlAccessType.PROPERTY而不是XmlAccessType.FIELD :

    @XmlRootElement
    @XmlAccessorType(XmlAccessType.PROPERTY)
    public static class ImageCap {
        private String filePath;
        private String caption;
        
...

此外,您会遇到的另一个问题是您拼写错误 getCaption <强> s ()作为复数,应该是 getCaption() 。 JAXB 也会提示它。

最后,通过在循环内编码(marshal)文件,您可以使用当前处理的 imageCap 一遍又一遍地重写同一文件。 。如果你想要的是编码所有 imageCap您需要将它们放在 List 上和编码(marshal)List反而。为此,您需要一个新的 JAXB 模型类,例如:

    @XmlRootElement(name = "myImageCapList")
    class ImageCapList {
        @XmlElement
        List<ImageCap> imageCap;

        public ImageCapList() {}

        public ImageCapList(List<ImageCap> imageCaps) {
            this.imageCap = imageCaps;
        }
    }

并且您需要创建该对象的一个​​实例来包装您的 ImageCap 列表对象 ( List<ImageCap> ) 并将其用作调用 jaxbMarshaller.marshal 的目标方法如下所示:

    public void imageCapsMarshal(List<ImageCap> imageCaps, File outFile) {
        try {
            jaxbMarshaller.marshal(new ImageCapList(imageCaps), outFile);
        } catch (JAXBException e) {
            // HANDLE EXCEPTIONS
        }
    }

此外,您还需要实例化您的 JAXBContext适本地:

    jaxbContext = JAXBContext.newInstance(ImageCapList.class);

以下是一个完整的工作演示供您使用:

import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

public class JAXBMarshall {
    
    private JAXBContext jaxbContext;
    private Marshaller jaxbMarshaller;

    public JAXBMarshall() throws JAXBException {
        jaxbContext = JAXBContext.newInstance(ImageCapList.class);
        jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    }

    public void imageCapsMarshal(List<ImageCap> imageCaps, File outFile) {
        try {
            jaxbMarshaller.marshal(new ImageCapList(imageCaps), outFile);
        } catch (JAXBException e) {
            // HANDLE EXCEPTIONS
        }
    }

    
    public static void main(String[] args) throws JAXBException {
        JAXBMarshall jaxbMarshaller = new JAXBMarshall();

        File file = new File("file.xml");
        List<ImageCap> imageCaps = IntStream.range(0, 10)
                .mapToObj(idx -> new ImageCap("my/file/path/" + idx, idx + ". The Caption!"))
                .collect(Collectors.toList());
        jaxbMarshaller.imageCapsMarshal(imageCaps, file);
    }

    @XmlRootElement(name = "myImageCapList")
    static class ImageCapList {
        @XmlElement
        List<ImageCap> imageCap;

        public ImageCapList() {}

        public ImageCapList(List<ImageCap> imageCaps) {
            this.imageCap = imageCaps;
        }
    }

    @XmlRootElement
    static class ImageCap {
        @XmlElement
        String filePath;

        @XmlElement
        String caption;
        
        public ImageCap() {}
        
        public ImageCap(String filePath, String caption) {
            this.filePath = filePath;
            this.caption = caption;
        }
        
        @Override
        public String toString() {
            return "ImageCap{" + "filePath=" + filePath + ", caption=" + caption + '}';
        }
    }
}

Complete code on GitHub

希望这有帮助。

关于java - XML JAXB 编码未保存到 xml 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56266633/

相关文章:

java - 将类对象发送到阶段 Controller - javafx

java - 用于 java 或 android 的 ePub 库

xml - 使用 VBA 获取 XML 中的所有属性和值

JavaFX:如何在向 TableView 添加列时显示动画 ProgressIndicator?

JavaFX 创建透明径向渐变

java - 如何正确组织类代码?

java - 有没有从javascript到Java bean(spring bean)执行RPC的框架?

xml - 在 Dart/Flutter 中解析嵌套的 XML

python - 在rml报告中设置两种语言

javafx - 如何从 javafx 应用程序打开默认系统浏览器?