5

I'm programming a simple Java game and I wanted to save to player data to an XML encoded save file. Currently I'm discovering the Java XML DOM API and I have a short question.

Suppose I have the following XML file (doesn't make sense I know, but it is just an example)

<?xml version="1.0"?>
<savedGame>
    <name></name>
    <player>
        <name>YOU</name>
        <map>
                        <health>2000</health>
            <name>map_test.map</name>
            <position>
                <x>0</x>
                <y>0</y>
            </position>
        </map>
        <stats>
            <health>1000</health>
            <xp>
                <melee></melee>
                <magic></magic>
                <ranged></ranged>
                <agility></agility>
            </xp>
        </stats>
        <items>
            <item id="0">
                <amount></amount>
            </item>
        </items>
    </player>
</savedGame>

Now I want to get the players health level (note that there is an other health element in the map section). This can be done with the following code:

String hp = ((Element) ((Element) savedGameDocument.getElementsByTagName("player").item(0)).getElementsByTagName("stats").item(0)).getElementsByTagName("health").item(0).getTextContent()

It works, yes. But it looks very nasty to me. Is this the usual way for getting those nested elements? And why isn't there an ElementList class? Now I have to cast every Node.

Thanks in advance, Jori.

3
  • 1
    Have a look at JAXB. It lets you work with yourjava object model, and takes over serialization to XML. Commented May 10, 2013 at 10:24
  • Well thanks, I will look at it. But if this is the best way to do it with just the normal Java XML API I'am happy too. Commented May 10, 2013 at 10:30
  • JAXB (JSR-222) is part of the normal Java XML API included in the JDK/JRE (see the javax.xml.bind package). Commented May 10, 2013 at 11:09

2 Answers 2

4

You can use the javax.xml.xpath APIs included on the JDK/JRE to easily get data from your do document.

import javax.xml.xpath.*;
import org.xml.sax.InputSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        XPathFactory xpf = XPathFactory.newInstance();
        XPath xpath = xpf.newXPath();

        InputSource xml = new InputSource("src/forum16479976/input.xml");
        String health = (String) xpath.evaluate("/savedGame/player/stats/health", xml, XPathConstants.STRING);
        System.out.println(health);
    }

}

These APIs also work accessing data from a DOM

import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.Document;

public class Demo {

    public static void main(String[] args) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document xml = db.parse("src/forum16479976/input.xml");

        XPathFactory xpf = XPathFactory.newInstance();
        XPath xpath = xpf.newXPath();
        String health = (String) xpath.evaluate("/savedGame/player/stats/health", xml, XPathConstants.STRING);
        System.out.println(health);
    }

}
Sign up to request clarification or add additional context in comments.

Comments

1

If you do this a lot, you can let a simple serializer handle this. You write Objects and read objects (like player etc), serializer takes care of the XML part. While you focus on game development.

As of manually parsing an XML from DOM, the logic you are already using can't be made smaller anymore. That is because, DOM provides very very basic methods of navigation : listing child nodes and picking one of them, repeat until reach the required node. This may be good for lightweight XML, but soon turns into a nightmare when you have parse intricate structures with many tag levels.

Another faster way is streaming, still, the more complicated XML structure gets , so does the parser code.

XPATH is also great if you just need to query the XML for just a particular node. But if you need full xml to objects transforms, use a serializer.

9 Comments

That looks very interesting, especially when working with a lot of save game data this could be very useful. But also, please refer back to my original question. :-)
You can use the javax.xml.xpath APIs in the JDK/JRE to make data access from a DOM easy: stackoverflow.com/a/16480432/383861
Last two questions: where can I find the annotations used in the document provided (simple.sourceforge.net/download/stream/doc/tutorial/…)? Binary serialization vs XML serialization, when should I use what? Thanks in advance!
@Jori Download and add jar as library in your project, annotations will become available. Use xml if you need to transfer data, or some one else is going to use it, because xml is easily readable (easy debugging :) ). Otherwise you can store it in binary only.
Ah, it is not part of the default Java API, that explains a lot. But isn't binary serialization a lot faster?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.