Andy
Andy

Reputation: 206

Exporting to XML, including embedded classes

I have an object config which has some properties. I can export this ok, however, it also has an ArrayList which relates to embedded classes which I can't get to appear when I export to XML. Any pointers would be helpful.

Export Method

public String exportXML(config conf, String path) {
    String success = "";
    try {
        FileOutputStream fstream = new FileOutputStream(path);
        try {
            XMLEncoder ostream = new XMLEncoder(fstream);
            try {
                ostream.writeObject(conf);
                ostream.flush();
            } finally {
                ostream.close();
            }
        } finally {
            fstream.close();
        }
    } catch (Exception ex) {
        success = ex.getLocalizedMessage();
    }
    return success;
}

Config Class (some detail stripped to keep size down)

public class config {

protected String author = "";
protected String website = "";
private ArrayList questions = new ArrayList();

public config(){
}

public void addQuestion(String name) {
    questions.add(new question(questions.size(), name));
}

public void removeQuestion(int id) {
    questions.remove(id);
    for (int c = 0; c <= questions.size(); c++) {
        question q = (question) (questions.get(id));
        q.setId(c);
    }
    questions.trimToSize();
}

public config.question getQuestion(int id){
    return (question)questions.get(id);
}


/**
 * There can be multiple questions per config.
 * Questions store all the information regarding what questions are
 * asked of the user, including images, descriptions, and answers.
 */
public class question {

    protected int id;
    protected String title;
    protected ArrayList answers;

    public question(int id, String title) {
        this.id = id;
        this.title = title;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void addAnswer(String name) {
        answers.add(new answer(answers.size(), name));
    }

    public void removeAnswer(int id) {
        answers.remove(id);
        for (int c = 0; c <= answers.size(); c++) {
            answer a = (answer) (answers.get(id));
            a.setId(c);
        }
        answers.trimToSize();
    }

    public config.question.answer getAnswer(int id){
        return (answer)answers.get(id);
    }

    public class answer {

        protected int id;
        protected String title;

        public answer(int id, String title) {
            this.id = id;
            this.title = title;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }
    }
}

}

Resultant XML File

<?xml version="1.0" encoding="UTF-8"?> 
<java version="1.6.0_18" class="java.beans.XMLDecoder"> 
 <object class="libConfig.config"> 
  <void property="appName"> 
   <string>xxx</string> 
  </void> 
  <void property="author"> 
   <string>Andy</string> 
  </void> 
  <void property="website"> 
   <string>www.example.com/dsx.xml</string> 
  </void> 
 </object> 
</java> 

Upvotes: 5

Views: 2209

Answers (3)

Ola Str&#246;m
Ola Str&#246;m

Reputation: 5301

Jackson is a competent library that started as a JSON library/parser but now has support for XML as well as Smile, (Java) Properties, YAML, CSV, CBOR, TOML, Avro, Protobuf and more.

For XML, you could use it like this:

/**
 * A method to write all the questions in xml format to a file.
 * @return                 a boolean;
 *                         true if successful,
 *                         false if not successful
 */
private static boolean writeQuestionsToXml() {
    XmlMapper xmlMapper = new XmlMapper();
    String absolutePath = getQuestionsAbsolutePath();

    try {
        xmlMapper.writeValue(new File(absolutePath), questions);
//        System.out.println(new XMLMapper().writeValueAsString(questions));
        return true;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return false;
}

/**
 * A method to get the absolute path to the questions file.
 * E.g.: "D:\Project\questions.xml"
 * @return                 a string with the absolute path to the questions file
 */
private static String getQuestionsAbsolutePath () {
    return "" + System.getProperty("user.dir") + "\\" + "questions.xml"
}

Some useful links:
How to Marshal and Unmarshal XML with Jackson
Libraries - IntelliJ IDEA Documentation

Upvotes: 1

Persimmonium
Persimmonium

Reputation: 15791

Xstream deals with this much better, from their description:

  • Requires no modifications to objects.
  • Serializes internal fields, including private and final.
  • Supports non-public and inner classes.
  • Classes are not required to have default constructor.

Upvotes: 2

Chris Lercher
Chris Lercher

Reputation: 37778

XMLEncoder works on public getters and setters: http://www.exampledepot.com/egs/java.beans/WriteXml.html

I wonder, why the other properties (like author) are in the file at all (?) Try adding public getQuestions() and setQuestions() methods.

Upvotes: 0

Related Questions