iDevGames Forums
XML Parsing - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Programming Languages & Scripting (/forum-8.html)
+--- Thread: XML Parsing (/thread-6180.html)



XML Parsing - Nick - Oct 14, 2004 06:48 PM

I'm currently looking into XML Parsing. I'm trying to figure out TinyXML but really I just need a cross platform way of parsing in some XML. Below is a sample file. I've never done anything with XML before so I'm not sure 1) if the following is "legal" XML or 2) how to set the code into action.

Code:
<level number="1">
    <level_width>50</level_width>
    <level_height>20</level_height>
    <number_blocks>10</number_blocks>
    <block><x>0</x><y>0</y><z>0</z><w>50</w><h>1</h></block>
    <block><x>7</x><y>3</y><z>0</z><w>4</w><h>1</h></block>
    <block><x>10</x><y>2</y><z>0</z><w>4</w><h>1</h></block>
    <block><x>29</x><y>3</y><z>0</z><w>1</w><h>1</h></block>
    <block><x>33</x><y>3</y><z>0</z><w>1</w><h>1</h></block>
    <block><x>31</x><y>7</y><z>0</z><w>1</w><h>1</h></block>
    <block><x>22</x><y>1</y><z>0</z><w>1</w><h>1</h></block>
    <block><x>42</x><y>1</y><z>0</z><w>1</w><h>1</h></block>
    <block><x>50</x><y>1</y><z>0</z><w>1</w><h>20</h></block>
    <block><x>0</x><y>1</y><z>0</z><w>1</w><h>20</h></block>
    <player><x>2</x><y>2</y><z>0</z><w>1</w><h>2</h></player>
</level>

An example of the code using these numbers:
block.Init(x,y,z,w,h);
player.Init(x,y,z,w,h);
LevelWidth = <level_width>
MyLevel = number


If anyone could help me or point me in the right direction to start importing this, I would really appreciate it.


XML Parsing - FCCovett - Oct 14, 2004 07:39 PM

Cross-platform is going to be a headache. I've got some sample code that uses Carbon, if you change your mind.

This seems to be a good reference, if you want to know more about XML: http://www.alistapart.com/topics/xml/


XML Parsing - Nick - Oct 14, 2004 08:02 PM

I think TinyXML is cross platform but I'm really new so what do I know? I'll look at that page a bit. It isn't so much the concept of XML but the actual code portion that I was unable to find good help with. Hopefully this link helps me out.


XML Parsing - Josh - Oct 14, 2004 08:09 PM

The Yoink source code uses TinyXML, if you can find it.


XML Parsing - Nick - Oct 14, 2004 08:42 PM

Yes I tried to look at that but between what he admits is sloppy coding along with the complexity of the code (or at least by appearance) it doesn't make for a good beginner's material.


XML Parsing - FCCovett - Oct 14, 2004 10:51 PM

The Apple developer's web-site has documentation on how to use Carbon or Cocoa to parse XML files, with some good examples and sample code. I got my stuff from there.

Now, there's a way to save and retrieve CF (Core Foundations) objects directly to and from XML files that is very convenient. It uses a proprietary scheme from Apple, but it's more than enough for games. For instance, if you have a CFString, or a CFArray (or their NS counterparts), you can put that all into a file. Check it out.


XML Parsing - Zekaric - Oct 15, 2004 08:59 AM

1/ yup that's proper XML.

2/ I haven't dealt with tinyxml so I can't comment on that. I have used libxml2 ( http://www.xmlsoft.org used by the gnome guys ) but I haven't tried to compile it on the mac yet. It should compile as far as I know as it's cross platform with windows and linux and shouldn't really be using anything other than standard 'C'. You might just want to use the basic build of the lib and not get into the uglies of iconv and gettext to make this lib really complete.

I code on windows at work but noobie coder for the mac at home so my opinion may be bogus.


XML Parsing - NCarter - Oct 15, 2004 04:08 PM

SimReality/Nick Wrote:Yes I tried to look at that but between what he admits is sloppy coding along with the complexity of the code (or at least by appearance) it doesn't make for a good beginner's material.
Hey, that's the good, non-disorganised part of the program! Wink

A few suggestions:

Don't make your XML hierarchy really complicated unless you really have to. The more your objects are nested inside one another, the harder it is to make sense of them when you iterate through them.

Do everything with attributes rather than child elements if you can. For example:

Code:
<level number="1">
    <level width="50" height="20"/>

    <block x="0" y="0" z="0" w="50" h="1"/>
    <block x="7" y="3" z="0" w="4" h="1"/>
    ...
        <player x="2" y="2" z="0" w="1" h="2"/>
</level>
That's a lot terser and it's easier to parse with TinyXML. I also omitted the <number_blocks>10</number_blocks> element because in my opinion, you shouldn't have to specify how many blocks there will be in advance; just count them and allocate memory for them as appropriate.

Here's a snippet of my TinyXML-based preferences code from Rescue:

Code:
TiXmlDocument document(filename);
bool success = document.LoadFile();
if(not success)
    return;

int value = 0;
const char *text = NULL;
TiXmlElement *element = document.RootElement();
if(element)
    element = element->FirstChildElement();

while(element)
{
    std::string element_name(element->Value());
    if(element_name == "window")
    {
        if(element->Attribute("width", &value))
        {
            if(value >= 640)
                mWindowWidth = value;
        }

        if(element->Attribute("height", &value))
        {
            if(value >= 480)
                mWindowHeight = value;
        }

        if(element->Attribute("depth", &value))
        {
            if(value == 16 or value == 32)
                mWindowDepth = value;
        }
    }
    else if(element_name == "mouse")
    {
        text = element->Attribute("scaling");
        if(text)
        {
            Ng::Float mouse_scaling = strtod(text, NULL);
            if(mouse_scaling > 0.0 and mouse_scaling < 20.0)
                mMouseScaling = mouse_scaling;
        }
    }
    else if(element_name == "stars")
    {
        if(element->Attribute("quantity", &value))
        {
            if(value >= 0)
                mStarQuantity = value;
        }
    }

    element = element->NextSiblingElement();
}
It's pretty simple. You just create a TiXmlDocument, tell it to load the file, find the root element (and examine its attributes if you want), then iterate through the root's children. For each child, you examine its name (.Value()) and attributes and perform an action based on that information. You could also either recurse into the child's children or skip over them - it's up to you.

Don't forget to read the TinyXML documentation. There isn't really much to it, and you don't need to bother with most of the methods. The ones you see in the code above are quite adequate for most purposes.


XML Parsing - Nick - Oct 17, 2004 07:00 PM

I've been working on TinyXML for a while now and I think I have the code all worked out but when I compile I get a linking error:

Code:
Building target “Sidescroller” with build style “Development” (optimization:level ‘0’, debug-symbols:on) — (1 error, 1 warning)
        /usr/bin/g++-3.3  -o "/Users/nicholasgravelyn/*Source Code*/Sidescroller/build/Sidescroller.app/Contents/MacOS/Sidescroller"  "-L/Users/nicholasgravelyn/*Source Code*/Sidescroller/build"  "-F/Users/nicholasgravelyn/*Source Code*/Sidescroller/build" "-F/Users/nicholasgravelyn/Library/Frameworks"  -filelist "/Users/nicholasgravelyn/*Source Code*/Sidescroller/build/Sidescroller.build/Sidescroller.build/Objects-normal/LinkFileList"  "-arch" "ppc" "-prebind" "-Wl,-no_arch_warnings" "-framework" "SDL"   "-framework" "Cocoa" "-framework" "OpenGL" "-framework" "SDL"
ld: multiple definitions of symbol _main
/Users/nicholasgravelyn/*Source Code*/Sidescroller/build/Sidescroller.build/Sidescroller.build/Objects-normal/ppc/SDLMain.o definition of _main in section (__TEXT,__text)
/Users/nicholasgravelyn/*Source Code*/Sidescroller/build/Sidescroller.build/Sidescroller.build/Objects-normal/ppc/xmltest.o definition of _main in section (__TEXT,__text)
ld: warning prebinding disabled because dependent library: /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit can't be searched
        ld: multiple definitions of symbol _main
        ld: warning prebinding disabled because dependent library: /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit can't be searched
Any ideas?


XML Parsing - NCarter - Oct 17, 2004 11:38 PM

Just remove the file xmltest.cpp from your project. It's an example app with its own main() function, so you don't need it to use the library.


XML Parsing - Nick - Oct 18, 2004 06:57 AM

I deleted xmltest.cpp and I'm still getting the error. Do I have to do more than just delete the file?


XML Parsing - DoG - Oct 18, 2004 08:57 AM

Clean & Rebuild the project. The already compiled .o isn't removed until then.


XML Parsing - Nick - Oct 18, 2004 11:22 AM

I didn't do the clean and rebuild but I did shut down Xcode and restart my computer (for another reason) and now it works. My XML imports correctly and it's pretty cool. Now to continue on making a level editor to make my job easier.