0

I am trying to ummarshal XML file that contains multiple objects, but not a List of Objects. I am not storing a List because I need to append single objects quite frequently.

Here is what the generated through marshalling XML looks like:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<message>
    <datetime>2015-03-26T10:33:52.540+02:00</datetime>
    <id>1</id>
    <rawChat>
        <members_ids>1</members_ids>
        <members_ids>2</members_ids>
    </rawChat>
    <sender>
        <id>1</id>
        <username>teso</username>
    </sender>
    <text>hello</text>
</message>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<message>
    <datetime>2015-03-26T10:38:59.576+02:00</datetime>
    <id>2</id>
    <rawChat>
        <members_ids>1</members_ids>
        <members_ids>2</members_ids>
    </rawChat>
    <sender>
        <id>1</id>
        <username>teso</username>
    </sender>
    <text>msg2</text>
</message>

And here is how I have marshalled it:

public void marshal(Message message) {
        try {
            JAXBContext jc = JAXBContext.newInstance(Message.class);
            Marshaller m = jc.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            m.marshal(message, new FileOutputStream("messages.xml", true));
            m.marshal(message, System.out);
        } catch (JAXBException | IOException e) {
            e.printStackTrace();
        }
    }

I need to unmarshall all the messages. Could you please give me some ideas how to do it?

  • This is not valid XML - you cannot have [multiple root elements](http://stackoverflow.com/questions/5042902/xml-error-there-are-multiple-root-elements). JAXB will not help you here! You need to enclose the `message` objects in a `messages` root object. You can then, for example, loop over the file with StaX and unmarshall each message individually. – Boris the Spider Mar 26 '15 at 08:49
  • From your comments it looks to me like you need to file based database, not XML. Perhaps [SQLite](https://sqlite.org/) or [hsqldb](http://hsqldb.org/). – Boris the Spider Mar 26 '15 at 08:55
  • The idea of this is to store chat messages on the client side, not on server database, that's why I need something like this. –  Mar 26 '15 at 08:56
  • 1
    Read above: **file based database**. This is how **almost every** application stores its data - for example iTunes (used to) use SQLLite. Don't reinvent the wheel, especially if you can't draw a circle... – Boris the Spider Mar 26 '15 at 08:58

2 Answers2

0

Split your XML file first. Then you can unmarshall each part to a message object instance.

You may also consider using a message store containing a list of Message. Working with a list should not impact negatively. Your XML would look like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<messsages>
  <message>
    ...
  </message>
</messages>

This is a valid XML that could be unmarshalled with JAXB with a single step. If you are working with a large number of Message than you shouldn't serialize them to XML. If the purpose is to persist them than you should implement another strategy more flexible and that takes into account the issues involved when persisting data.

Olivier Meurice
  • 554
  • 8
  • 17
  • I thought about it, but I need to store hundreds of messages and I don't want to have 100+ files. Thanks though! –  Mar 26 '15 at 08:49
  • 1
    @SteveWalk as mentioned, this is not XML, its SML (Steve Markup Language). If there were a JASB (Java API for Steve (ML) Binding) then you'd be good to go. As it stands you need to make some changes. – Boris the Spider Mar 26 '15 at 08:51
0

That isn't valid XML - in fact it looks like multiple XML files concatenated: XML needs a single root element (and in fact, repeating the XML Prolog is probably invalid too).

A list is designed to append single objects quite frequently, so this should be fine.

declension
  • 4,110
  • 22
  • 25
  • 1
    Although if this is a file, in order to append an element then entire file needs to be read and rewritten to append an element. So there is an issue with that, just depends on how often "fairly" is. – Boris the Spider Mar 26 '15 at 08:53
  • I didn't want to keep up in memory the whole list and rewrite the file each time a new object is added. Is there a way to avoid this? –  Mar 26 '15 at 08:55
  • 1
    @SteveWalk yes. Don't use XML. ALternatively, read about the streaming APIs - but if your application crashes without finishing writing the XML it will be corrupt. – Boris the Spider Mar 26 '15 at 08:56