我想用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();
答案 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");
}