XMLEnocder mess.. (Java)

Soldato
Joined
23 Dec 2010
Posts
3,483
Hey guys,

I posted a similar thread earlier on in the month, but there seemed to be some sort of confusion regarding what I was actually asking.

For one of our modules we were asked to create a program which takes some objects and stores them into files using three different methods – Text, XML and Serializable.

I was able to do Serializable and Text, but I seem to be having some confusion with XML.

I have two classes, Books and Authors.

Books are set into the Author using names – so the code looks something akin to this..

Book class -

Instance = private Author who;

Code:
public void setAuthor(ArrayList<Author> authors) {  
         this.who = who;
 }

and in the Author class..
.
Code:
     public void setBooks(ArrayList<Book> books) {
         this.books = books;
     }
 

     public ArrayList<Book> getBooks() {
         return books;
     }

This is what the XML code looks like..


Code:
 public void writeXML(String fn) throws IOException {
 

         XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(
                 new FileOutputStream(fn)));
         encoder.writeObject(this);
         encoder.close();
 

         }

This is found in the 'model' class which takes user input and stores them into ArrayLists.

However, whenever I save in XML I get..

Code:
 <?xml version="1.0" encoding="UTF-8"?>
 <java version="1.7.0_09" class="java.beans.XMLDecoder">
  <object class="Model"/>
 </java>

I hope that's enough information regarding my issue, if any of you can help then I'll forever be thankful!

Thanks

Also, all of the code can be found here.
 
Ok ... now I'm looking on a screen big enough to look at your pastebin post, I can see the Book class has two setAuthor() methods. One taking a single Author object and the other (posted above) that takes an array. However, the 'who' member is a single author, so the array version isn't going to make sense. You need to either:

- Remove it. Does your model need to support multiple authors of a single book ?
- Choose one author (e.g. the first one) from the array you're passing in and set 'who' to that
- Change the who member to be an array of authors (and change the single author setter to handle this)


At the moment, the "Book" bean is inconsistent and I think that's stuffing up the reflection/introspection used by the XMLEncoder class.

The book can only support one model.

I don't quite understand what you want me to do?
 
Your Book class has an Author,

private Author who;

but you have a setter method with an ArrayList as an argument which doesn't make sense. An instance of Book can only ever have 1 Author instance set to it.

The question is, is this setter just a mistake/error or did you intend for a Book to have multiple Authors?

I didn't want the book to have many authors.

I don't see where I've done that?
 
Ok, then as peterwalkley has suggested, something needs to be done regarding the "public void setAuthor(ArrayList<Author> authors)" method on the Book class.

in your original post you were setting

this.who = who;

which probably wont do anything at all as your are just pointing 'who' at it's self.
setting this.who = authors; wont work either as you are trying to assign a reference to an ArrayList to an Author object (which aren't of the same type).

However, you do already have a valid setter "public void setAuthor(Author who)", so just wondering what the need for overloading was for?

So get rid of this.who = who;?
 
Thanks for the complement, but I will say that some of the people here at Uni are absolutely amazing at programming - I'm nothing in comparison.

I'll just try my hardest to catch up.

I'll give that a go in a bit.
 
Thanks for all of the help guys, I've just got one more issue now.

We have to save the information as 'human readable text' now.

I've done methods for the save which look like this.

Code:
/* -------------------- Saving and Loading Text -------------------- */

    public void saveTextBook(String fn) throws IOException {
        PrintWriter outfile = new PrintWriter(new OutputStreamWriter(
                new FileOutputStream(fn)));

        outfile.println(books.size());

        for (Book b : books) {
            outfile.println(b.getTitle());
            outfile.println(b.getPrice());
            outfile.println(b.getAuthor().getName());
        }

        outfile.close();
    }

    public void saveTextAuthor(String fn) throws IOException {
        PrintWriter outfile = new PrintWriter(new OutputStreamWriter(
                new FileOutputStream(fn)));

        outfile.println(authors.size());

        for (Author a : authors) {
            outfile.println(a.getName());
            outfile.println(a.getNationality());
        }
        outfile.close();
    }

    public void loadTextBook(String fn) throws IOException {
        Scanner infile = new Scanner(new InputStreamReader(new FileInputStream(
                fn)));

        int num = infile.nextInt();
        infile.nextLine();

        for (int i = 0; i < num; i++) {
            String t = infile.nextLine();
            double p = infile.nextDouble();
        }
        infile.close();

    }

    public void loadTextAuthor(String fn) throws IOException {
        Scanner infile = new Scanner(new InputStreamReader(new FileInputStream(
                fn)));

        int num = infile.nextInt();
        infile.nextLine();

        for (int i = 0; i < num; i++) {
            String n = infile.nextLine();
            String nat = infile.nextLine();            
            
        }
        infile.close();
    }

How would I go about loading this directly from the file?

As you can see, the load methods are there - but they don't work!

Thanks.
 
Have you tried stepping through it with the debugger?

On first glance, assuming the file reading works, it's reading both into local string variables and then doing nothing with them before looping round again.

Presumable you need to instantiate / clear the lists and add new Author and Book objects to them which are created from these locals.

Pardon?
 
Back
Top Bottom