java - 将列表编码为 XML 是可行的 - 但如何解码呢?

标签 java xml jaxb marshalling

我可以使用“Wrapper”类来编码 ObservableList,如下所示。但我无法将其解码回之前的包装类。

这个想法是: 我有一个“费用”的可观察列表。我将此列表放入包装类中,并将该类保存为 XML。结果如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<List>
    <root>
        <category>[none]</category>
        <period>Year</period>
        <title>asd</title>
        <value>354</value>
    </root>
</List>

我无法将其带回包装对象。 我真的很感谢任何形式的帮助。

主类 JAXBContext(对所有人可见):

JAXBContext jc = JAXBContext.newInstance(MyWrapperForList.class, Expense.class);

主类保存按钮:

public class SaveButtonListener implements EventHandler<ActionEvent> {

    @Override
    public void handle(ActionEvent arg0) {

        File serializedFile = new File(PATH);

        try {
            if (serializedFile.exists() == false)
            serializedFile.createNewFile();

            PrintWriter xmlOut = new PrintWriter(serializedFile);

            Marshaller m = jc.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            List<Expense> saveList = new ArrayList<>();

            saveList.addAll(data);



            MyWrapperForList<Expense> wrapper = new MyWrapperForList<>(saveList);
                JAXBElement<MyWrapperForList> jaxbElement = new JAXBElement<>(
new QName("List"), MyWrapperForList.class, wrapper);



        m.marshal(jaxbElement, xmlOut);

            xmlOut.flush();
            xmlOut.close();

主类-LOADBUTTON:

public class LoadButtonListener implements EventHandler<ActionEvent> {

    @Override
    public void handle(ActionEvent arg0) {


        try {
            Unmarshaller unmarshaller = jc.createUnmarshaller();




StreamSource xml = new StreamSource(PATH);
                MyWrapperForList<Expense> unwrapper = unmarshaller.unmarshal(xml,
 MyWrapperForList.class).getValue();

            List<Expense> tempList = new ArrayList<>();
            tempList.addAll(unwrapper.getItems());


            System.out.println(tempList.get(0).getTitle());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

包装类:

公共(public)类MyWrapperForList {

private List<Expense> list;

public MyWrapperForList() {
    list = new ArrayList<>();
}

public MyWrapperForList(List<Expense> expenses) {
    this.list = expenses;
}

@XmlAnyElement(lax=true)
public List<Expense> getItems() {
    return list;
}

}

费用类别:

@XmlRootElement(名称 = "根") 公开课费用{

private String title;
private String category;
private String period;
private String value;

public Expense() {} //Default constructor is needed for XML-handling

public Expense(String title, String value, String period, String category) {
    this.title = title;
    this.value = value;
    this.period = period;
    this.category = category;
}

@XmlElement(name = "title")
public String getTitle() {
    return this.title;
}

@XmlElement(name = "category")
public String getCategory() {
    return this.category;
}

@XmlElement(name = "period")
public String getPeriod() {
    return this.period;
}

@XmlElement(name = "value")
public String getValue() {
    return this.value;
}

}

我使用了 Blaise Doughan 的教程:http://blog.bdoughan.com/2012/11/creating-generic-list-wrapper-in-jaxb.html

最佳答案

MyListWrapper

如果您希望 MyWrapperForList 解码持有 ObservableList 的实例,那么您需要通过以下方式之一设置您的类。

ObservableList类型的属性

import javax.xml.bind.annotation.XmlAnyElement;
import javafx.collections.*;

public class MyWrapperForList<T> {

    private ObservableList<T> list;

    public MyWrapperForList() {
        list = FXCollections.<T>observableArrayList();
    }

    public MyWrapperForList(ObservableList<T> list) {
        this.list = list;
    }

    @XmlAnyElement(lax = true)
    public ObservableList<T> getItems() {
        return list;
    }

}

List 属性初始化为 ObservableList

的实例
import java.util.List;
import javax.xml.bind.annotation.XmlAnyElement;
import javafx.collections.*;

public class MyWrapperForList<T> {

    private List<T> list = FXCollections.<T>observableArrayList();

    public MyWrapperForList() {
        list = FXCollections.<T>observableArrayList();
    }

    public MyWrapperForList(List<T> list) {
        this.list = list;
    }

    @XmlAnyElement(lax = true)
    public List<T> getItems() {
        return list;
    }

}

演示代码

输入(nub.xml)

<List>
    <root>
        <category>[none]</category>
        <period>Year</period>
        <title>dfg</title>
        <value>4</value>
    </root>
    <root>
        <category>[none]</category>
        <period>Year</period>
        <title>ROBO</title>
        <value>1234</value>
    </root>
</List>

演示

import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(MyWrapperForList.class, Expense.class);

        //UNMARSHALLING
        Unmarshaller unmarshaller = jc.createUnmarshaller();

        StreamSource xml = new StreamSource("src/forum18594548/nub.xml");
        MyWrapperForList<Expense> wrapper = (MyWrapperForList<Expense>) unmarshaller.unmarshal(xml, MyWrapperForList.class).getValue();
        List<Expense> data = wrapper.getItems();

        System.out.println(data.getClass());
        for(Expense expense : data) {
            System.out.println(expense);
        }
   }

}

输出

class com.sun.javafx.collections.ObservableListWrapper
forum18594548.Expense@789df61d
forum18594548.Expense@4a8927c8
<小时/>

更新

First: Thanks for you work Blaise!! I'm really glad for what you do to me! I tried what you wrote here (it was nearly the same as I had) and I got a similar (same type of) output as you got. BUT the objects in the lists are all referenced with null. If I write System.out.println(data.get(0).getTitle()); it says null. There is the exact amount of objects in the list, but all attributes are referenced with null. :(

我认为我对 ObservableList 方面的视野很狭隘,只是忽略了您真正的问题是如何映射 Expense 类。由于您只有 get 方法,因此应使用 @XmlAccessorType(XmlAccessType.FIELD) 映射到字段,如下所示。

import javax.xml.bind.annotation.*;

@XmlRootElement(name="root")
@XmlAccessorType(XmlAccessType.FIELD)
public class Expense {

    private String title;
    private String category;
    private String period;
    private String value;

    public Expense() {
    }

    public Expense(String title, String value, String period, String category) {
        this.title = title;
        this.value = value;
        this.period = period;
        this.category = category;
    }

    public String getTitle() {
        return this.title;
    }

    public String getCategory() {
        return this.category;
    }

    public String getPeriod() {
        return this.period;
    }

    public String getValue() {
        return this.value;
    }

}

关于java - 将列表编码为 XML 是可行的 - 但如何解码呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18594548/

相关文章:

java - 具有字符串限制的 WSDL 生成

java - 在 Spring 中配置系统属性

java - 在 Groovy 中获取正确版本的 Oracle 驱动程序

java - DOM 处理后 XML 属性的顺序

php - 将 XML 导入 MySQL 5.1

android - 菜单图标不出现,ics 4.0.3

java - 如何让 TitledBorder 的标题在 GUI 中正确显示

java - 用于枚举的 wsimport JAXB 类

java - JAXB 编码器和输出 XML 格式

java - 从 xsd :choice element 自定义 JAXB 2.0 生成的方法名称