【问题标题】:Java: How to store Vector<String[]> in XML (or save in any other way)Java:如何将 Vector<String[]> 存储在 XML 中(或以任何其他方式保存)
【发布时间】:2011-02-12 15:24:25
【问题描述】:

基本上,我有一个概念验证应用程序,它是一本数字食谱书。每个配方都是一个对象,每个对象除了其他字段外,还具有一个包含数组的向量。 Vector 是配方中所有成分的列表,而每种成分都有一个数组,显示成分的名称、数量和该数量的单位。我想将每个配方保存到 XML,以便用户可以访问它们。如何在 XML 或任何其他类型的文件中存储字符串数组的向量,以便以后可以调用和访问它?

【问题讨论】:

标签: java xml arrays vector save


【解决方案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)。

最好使用 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】:

    要快速启动,您可以使用XStream。默认情况下它会产生很好的输出,并且非常灵活,因此您可以在 XML 中获得几乎想要的内容。

    您可以通过编写将对象序列化为 XML

    String xml = XStream.toXML(myObject);
    

    关于结构,在事先不知道数量的情况下,可以继续使用向量和列表,但最好使用领域对象的列表(食谱、配料等)而不是字符串数组。使用 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>
    

    【讨论】:

      【解决方案3】:

      为什么不将成分也建模为真实对象?然后你有一个配方下的成分元素序列,每个都有自己的子元素或名称、数量、单位等属性。

      【讨论】:

      • 由于我希望程序工作的方式,数组向量更容易实现。主要是因为我不知道每个食谱需要多少成分。理想情况下,我想要一个不需要我更改应用程序结构的问题的答案。
      • 你可以让xml模式接受n个成分,你不需要事先知道。在我看来,在字符串中编码真正的领域对象是一种真正的代码味道。
      猜你喜欢
      • 2021-07-15
      • 2016-01-12
      • 2021-12-22
      • 2019-03-11
      • 2015-05-09
      • 1970-01-01
      • 1970-01-01
      • 2019-03-22
      • 2013-07-18
      相关资源
      最近更新 更多