2010-04-26 57 views
1

基本上我有一个概念验证应用程序,它是一个数字食谱书。每个配方都是一个对象,每个对象都有一个包含数组的Vector。 Vector是食谱中所有成分的列表,而每种成分都有一个列表,显示成分的名称,数量和单位。我想将每个食谱保存为XML,以便用户可以访问它们。如何以XML或任何其他类型的文件存储字符串数组的Vector,以便稍后可以调用和访问它?Java:如何以XML格式存储矢量<String[]>(或以任何其他方式保存)

+2

看看http://java.sun.com/developer/technicalArticles/Programming/serialization/ – Searles 2010-04-26 23:18:57

回答

1

有几种技术可以生成XML,每种都有自己的优点和缺点。最简单的实现(但最难做出的)是手动构建XML。

假设你希望你的成分表如下所示:

<ingredients> 
    <ingredient name="ginger"/> 
    <ingredient name="cinnamon"/> 
    <ingredient name="sugar"/> 
</ingredients> 

你需要你的代码走向量:

System.out.println("<ingredients>"); 
Vector ingredients; 
for (String name : ingredients) { 
    System.out.print(" <ingredient name=\""); 
    System.out.print(name); 
    System.out.println("\"/>"); 
} 
System.out.println("</ingredients>"); 

用这种方法的问题是,当你修改底层数据结构(在你的情况下,数组的矢量,你需要修改XML代码匹配(这往往导致不正确的XML)

它的muc最好使用XML库来生成XML。一个好的XML库将始终生成有效的XML。

import java.io.FileWriter; 
import com.megginson.sax.XMLWriter; 
import org.xml.sax.helpers.AttributesImpl; 

public class GenerateXML 
{ 

    public static void main (String args[]) 
    throws Exception 
    { 
    XMLWriter writer = new XMLWriter(new FileWriter("output.xml")); 

    writer.startDocument(); 
    writer.startElement("","ingredients","",null); 
    for (String ingredient : ingredients) { 
     AttributesImpl attribs = new AttributesImpl(); 
     attribs.addAttribute("","name","","",ingredient); 
     writer.startElement("", "ingredient","",attribs); 
     writer.endElement("ingredient"); 
    } 
    writer.endElement("ingredients"); 
    writer.endDocument(); 
} 

对于什么是可能与DOM XMLWriter就看http://docstore.mik.ua/orelly/xml/sax2/ch02_02.htm特别要注意第2.2.3节更完整的描述。

你也可以做一个DOM到XML转换,但使用DOM意味着你必须建立自己的数据结构,这可能是(你的情况),不必要的和不受欢迎的额外步骤的DOM表示。

顺便说一句,而你可能会喜欢的东西字符串数组的矢量开始,这样的数据结构有什么与什么配方需要现实世界的概念。从长远来看,您可能会更好地使用类Recipie,其中包含成分类和说明(其中包含步骤)。虽然它可能看起来像更多的工作打下了三个或四个不同类型的类,这项工作锋线保存在着手完成计划的最后10%的工作同等数额的十倍以上。

即使是概念的“快速”的证明,使用一个真正的描述性数据结构可以显著的节约时间;因为概念证明可能很快成为开始的原型,然后可能成为真正发布的基础。

祝你好运,快乐的编程!

2

为什么不将模型作为真实物体进行建模?然后你在配方下有一系列配料元素,每个配料元素都有自己的子元素或者名称,数量,单位等属性。

+0

由于我希望程序工作的方式,Vector的数组更容易实现。主要是由于我不知道每种配方需要多少配料。理想情况下,我想回答这个问题,并不需要我改变我的应用程序的结构。 – 2010-04-27 00:31:45

+0

可以使XML模式接受成分的N多,你不需要事先知道这一点。在我看来,在字符串内编码真实的域对象是一种真正的代码味道。 – 2010-04-27 09:18:59

0

要快速起步,可以使用XStream。它默认生成很好的输出,并且非常灵活,所以你可以在XML中获得你想要的东西。

您可以通过编写

String xml = XStream.toXML(myObject); 

至于结构序列化对象到XML,你可以继续使用向量和列表,当你不知道提前量,但最好使用域对象列表(食谱,配料等)而不是字符串数组。使用XStream,您不必将所有内容都设置为一个字符串来使用XML。

如果你确实想保留一切,因为它没有改变,那么默认的XStream行为可能不会给你你想要的。它不知道哪些字符串是食谱,配料等。在这种情况下,你必须写更多。例如,该代码将一个向量,如食谱成分于文件 “recipes.txt”:

Vector<String[]> recipes = ... (your vector of recipes) 
PrettyPrintWriter writer = new PrettyPrintWriter(new FileWriter("recipes.txt")); 
writer.startNode("recipes"); 
for (String[] recipe: recipes) 
{ 
    writer.startNode("recipe"); 
    // you might write out attributes, such as the recipe name 
    for (String ingredient: recipe) 
    { 
     writer.startNode("ingredient"); 
     writer.setValue(ingredient); 
     writer.endNode(); 
    } 
    writer.endNode(); 
} 
writer.endNode(); 
writer.close(); 

对于矢量

Vector<String[]> v = new Vector<String[]>(); 
v.add("2 cups pasta", "1 onion"); 
v.add("2 eggs", "1.5 cups sugar", "1 tbsp butter"); 

的输出将是

<recipes> 
    <recipe> 
     <ingredient>2 cups pasta</ingredient> 
     <ingredient>1 onion</ingredient> 
    </recipe> 
    <recipe> 
     <ingredient>2 eggs</ingredient> 
     <ingredient>1.5 cups sugar</ingredient> 
     <ingredient>1 tbsp butter</ingredient> 
    </recipe> 
</recipes> 
相关问题