使用JAXB编组ObservableList

时间:2015-10-17 18:58:35

标签: xml javafx jaxb

我想用JAXB编组一个对象“main”,这是根类的属性:

    private StringProperty mensaje;
    private bd database;
    private ObservableList<MarcoOntologicoColectivo> Inteligencia_colectiva=FXCollections.observableArrayList();
    private ObservableList<agent> agentData = FXCollections.observableArrayList();
    private ObservableList<MarcoOntologicoColectivo> Colectivo=FXCollections.observableArrayList();
    private ObservableList<MarcoOntologicoColectivo> Belongs=FXCollections.observableArrayList();

但由于某种原因(我不知道为什么)JAXB只接受属性数据库和mensaje,我需要保存observableList,这也是输出:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<main>
    <database>
        <a_mecanismo>Hebbiano</a_mecanismo>
        <a_tecnicas>Redes Neuronales</a_tecnicas>
        <a_tecnicas>Arboles de Decision</a_tecnicas>
        <a_tecnicas>Reglas</a_tecnicas>            <a_tipo>Supervisado</a_tipo>
        <a_tipo>No supervisado</a_tipo>
        <a_tipo>Reforzamiento</a_tipo>
        <actos_habla>Requerimiento de Procesamiento</actos_habla>
        <caracterizacion>Concepto</caracterizacion>
        <caracterizacion>Propiedad</caracterizacion>
        <r_estrategia>Deductivo</r_estrategia>
        <r_estrategia>Inductivo</r_estrategia>
        <r_estrategia>Abductivo</r_estrategia>
        <r_lenguaje>OWL</r_lenguaje>
        <r_lenguaje>RDF</r_lenguaje>
        <servicio>Interno</servicio>
        <servicio>Externo</servicio>
        <servicio>Dual</servicio>
        <tipo_datos>byte</tipo_datos>
        <tipo_datos>short</tipo_datos>
        <tipo_datos>int</tipo_datos>
    </database>
    <mensaje/>
</main>

那么,我哪里错了?我该怎么办?

我编辑了项目并为Observable List put添加了适配器:

public class ObservableListAdapter<T> extends XmlAdapter<LinkedList<T>, ObservableList<T>> {
        @Override
        public ObservableList<T> unmarshal(LinkedList<T> v) throws Exception {
            return FXCollections.observableList(v);
        }

        @Override
        public LinkedList<T> marshal(ObservableList<T> v) throws Exception {
            LinkedList<T> list = new LinkedList<T>();
            list.addAll(v);
            return list; // Or whatever the correct method is
        }
}

现在出现在XML文件中:

<belongs/>
 <colectivo/>
 <inteligencia_colectiva/>

但不会整理他们的内容,我该怎么办?

我像这样声明了JAXB Context:

File file = new File("file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(MyClass.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

2 个答案:

答案 0 :(得分:2)

以下是使用JAXB编组ObservableList的示例:

MyObject.java

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;

@XmlType(name = "Object")
public class MyObject {

    private String value;

    @XmlAttribute (name = "value", required = false)
    public String getvalue() {
        return value;
    }

    public void setvalue(String value) {
        this.value = value;
    }


    public String toString() {
        return "value=" + value;
    }
}

MyContainer.java

import java.util.List;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;


@XmlRootElement(name = "Container")
public class MyContainer extends MyObject {

    private ObservableList<MyObject> children = FXCollections.observableArrayList();

    @XmlElements({ @XmlElement(name = "Object", type = MyObject.class) })
    public List<MyObject> getChildren() {
        return children;
    }


    public String toString() {

        StringBuilder sb = new StringBuilder();
        sb.append("children:");

        for (MyObject node : children) {
            sb.append("\n");
            sb.append("  " + node.toString());
        }
        return sb.toString();

    }
}

Example.java

import java.io.StringReader;
import java.io.StringWriter;

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

public class Example {
    public static void main(String[] args) {

        // create container with list
        MyContainer container = new MyContainer();

        // add objects
        MyObject object;

        object = new MyObject();
        object.setvalue("A");
        container.getChildren().add( object);

        object = new MyObject();
        object.setvalue("B");
        container.getChildren().add( object);

        // marshal
        String baseXml = marshal( container);

        // unmarshal
        container = unmarshal(baseXml);

        System.out.println("Container:\n" + container);


        System.exit(0);
    }

    public static String marshal( MyContainer base) {

        try {

            JAXBContext jaxbContext = JAXBContext.newInstance(MyContainer.class);

            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            StringWriter stringWriter = new StringWriter();
            jaxbMarshaller.marshal(base, stringWriter);
            String xml = stringWriter.toString();

            System.out.println("XML:\n" + xml);

            return xml;

        } catch (Exception e) {
            throw new RuntimeException( e);
        }

    }

    public static MyContainer unmarshal( String xml) {

        try {

            JAXBContext jaxbContext = JAXBContext.newInstance(MyContainer.class);

            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            StringReader stringReader = new StringReader(xml);

            MyContainer container = (MyContainer) jaxbUnmarshaller.unmarshal(stringReader);

            return container;

        } catch (Exception e) {
            throw new RuntimeException( e);
        }

    }
}

控制台输出:

XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Container>
    <Object value="A"/>
    <Object value="B"/>
</Container>

Container:
children:
  value=A
  value=B

我不会解决您的确切问题,因为您提供的信息不完整,而且您并不打算用英语提供代码。下次需要帮助时,您应该考虑这一点。

答案 1 :(得分:0)

我使用了可接受的答案,并设法在每个食谱都有其自己的材料列表的情况下映射了食谱列表a。我希望这对想要实现类似目标的人有所帮助。

package pojos;

import java.io.Serializable;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;

import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;

@XmlType(name = "Material")
public class Material implements Serializable{

    private SimpleStringProperty itemName = new SimpleStringProperty();
    private SimpleIntegerProperty quantity = new SimpleIntegerProperty();

    public Material(){

    }

    public Material(
        String itemName,
        int quantity
    ){
        setItemName(itemName);
        setQuantity(quantity);
    }

    @XmlAttribute(name = "itemName")public String getItemName(){ return this.itemName.get();}
    @XmlAttribute(name = "quantity")public int getQuantity(){ return this.quantity.get();}

    public void setItemName(String itemName){ this.itemName.set(itemName);}
    public void setQuantity(int quantity){ this.quantity.set(quantity);}

    public SimpleStringProperty itemNameProperty(){ return this.itemName;}
    public SimpleIntegerProperty quantityProperty(){ return this.quantity;}

}

食谱:

package pojos;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

import org.apache.commons.io.FileUtils;

import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import utils.MyProperties;

@XmlType(name = "Recipe")
public class Recipe implements Serializable{

    private ObservableList<Material> materials = FXCollections.observableArrayList();
    private SimpleStringProperty itemName = new SimpleStringProperty();
    private SimpleBooleanProperty multipleChance = new SimpleBooleanProperty();
    private SimpleIntegerProperty craftedAmount = new SimpleIntegerProperty();

    public Recipe(){
    }

    public Recipe(
        String itemName,
        ObservableList<Material> materials,
        boolean multipleChance,
        int craftedAmount
    ){
        setItemName(itemName);
        setMaterials(materials);
        setMultipleChance(multipleChance);
        setCraftedAmount(craftedAmount);
    }

    @XmlAttribute(name = "itemName")public String getItemName(){ return this.itemName.get();}
    @XmlElementWrapper
    @XmlElements({ @XmlElement(name = "Material", type = Material.class) }) 
    public ObservableList<Material> getMaterials(){ return this.materials;}
    @XmlAttribute(name = "multipleChance")public boolean isMultipleChance(){ return this.multipleChance.get();}
    @XmlAttribute(name = "craftedAmount")public int getCraftedAmount(){ return this.craftedAmount.get();}

    public void setItemName(String itemName){ this.itemName.set(itemName);}
    public void setMaterials(List<Material> materials){ this.materials.setAll(materials);}
    public void setMultipleChance(boolean multipleChance){ this.multipleChance.set(multipleChance);}
    public void setCraftedAmount(int craftedAmount){ this.craftedAmount.set(craftedAmount);}

    public SimpleStringProperty itemNameProperty(){ return this.itemName;}
//  public SimpleObjectProperty<List<Material>>  materialsProperty(){ return this.materials;}
    public SimpleBooleanProperty multipleChanceProperty(){ return this.multipleChance;}
    public SimpleIntegerProperty craftedAmountProperty(){ return this.craftedAmount;}

    @XmlRootElement(name="RecipeList")
    public static class RecipeList {

        private ObservableList<Recipe> recipes = FXCollections.observableArrayList();

        public RecipeList() {
            // TODO Auto-generated constructor stub
        }

        @XmlElementWrapper

        @XmlElements({ @XmlElement(name = "Recipe", type = Recipe.class) })
        public ObservableList<Recipe> getRecipes() {
            return recipes;
        }

        public void setRecipes(ObservableList<Recipe> recipes) {
            this.recipes = recipes;
        }

    }

    public void saveRecipes(ObservableList<Recipe> recipes, String fileName) throws JAXBException, UnsupportedEncodingException, IOException {
        RecipeList recipeList = new RecipeList();
        recipeList.setRecipes(recipes);

        JAXBContext jaxbContext = JAXBContext.newInstance(RecipeList.class);

        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        StringWriter stringWriter = new StringWriter();
        jaxbMarshaller.marshal(recipeList, stringWriter);
        String xml = stringWriter.toString();

        FileUtils.writeStringToFile(new File(MyProperties.geneateFilepathInCurrentLocation(fileName+".xml")), xml, Charset.defaultCharset());

    }

    public ObservableList<Recipe> loadRecipes(String fileName) throws JAXBException, IOException{
        File file = new File(MyProperties.geneateFilepathInCurrentLocation(fileName+".xml"));
        JAXBContext jaxbContext = JAXBContext.newInstance(RecipeList.class);

        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        String text = 
                FileUtils.readFileToString(
                        file, 
                        Charset.defaultCharset()
                    );

        StringReader stringReader = new StringReader(
                text
        );

        return ((RecipeList) jaxbUnmarshaller.unmarshal(stringReader)).getRecipes();

    }

//  public static void main(String[] args) throws UnsupportedEncodingException, IOException, JAXBException {
//
//      if(false) {
////        if(true) {
//          RecipeList recipeList = new RecipeList();
//          Material material1 = new Material("mat1", 1);
//          Material material2 = new Material("mat2", 10);
//          ObservableList<Material> materials = FXCollections.observableList(Arrays.asList(material1, material2));
//          Recipe recipe = new Recipe("a", materials, false, 1);
//          recipeList.setRecipes(FXCollections.observableList(Arrays.asList(recipe)));
//          
//          JAXBContext jaxbContext = JAXBContext.newInstance(RecipeList.class);
//
//          Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
//          jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//
//          StringWriter stringWriter = new StringWriter();
//          jaxbMarshaller.marshal(recipeList, stringWriter);
//          String xml = stringWriter.toString();
//          System.out.println(xml);
//
//          FileUtils.writeStringToFile(new File(MyProperties.geneateFilepathInCurrentLocation("AlchemyRecipes.xml")), xml, Charset.defaultCharset());
//          
//      }else {
//          File file = new File(MyProperties.geneateFilepathInCurrentLocation("AlchemyRecipes.xml"));
//          JAXBContext jaxbContext = JAXBContext.newInstance(RecipeList.class);
//  
//          Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
//          String text = 
//                  FileUtils.readFileToString(
//                          file, 
//                          Charset.defaultCharset()
//                      );
//          
//          StringReader stringReader = new StringReader(
//                  text
//          );
//  
//          RecipeList container = (RecipeList) jaxbUnmarshaller.unmarshal(stringReader);
//  
//          container.getRecipes().forEach(e->{
//              System.out.println(e.getItemName());
//              System.out.println(e.getCraftedAmount());
//              System.out.println(e.isMultipleChance());
//              e.getMaterials().forEach(m->{
//                  System.out.println("\t"+m.getItemName());
//                  System.out.println("\t"+m.getQuantity());
//              });
//          });
//          
//        
//      }
//  }


}

MyProperties.geneateFilepathInCurrentLocation(fileName +“。xml”)是我用来在jar外部管理文件的一种方法。

public static final String geneateFilepathInCurrentLocation(String propertiesFileName) throws UnsupportedEncodingException {
        String jarPath = MyProperties.class.getProtectionDomain().getCodeSource().getLocation().getPath();
        int lastSlashIndex = jarPath.lastIndexOf("/");
        String parentFolder = jarPath.substring(0, lastSlashIndex);
        return URLDecoder.decode(parentFolder+ "/" + propertiesFileName, "UTF-8");
    }