PDA

View Full Version : XML -> Object


JkWhoSaysNi
06-25-2007, 06:24 PM
To go with the Object -> XML conversion I posted a while back: http://forums.graalonline.com/forums/showthread.php?t=74337

function readXML(filename,object) {
this.xml = new TStaticVar();
this.xml.loadlines(filename);
this.stack = {};
while(this.xml.size() > 0) {
temp.tag = getTagName(this.xml[0]);
if (startTag(this.xml[0])) {
this.stack.insert(0,temp.tag);
//object.(@varStack()) = new TStaticVar();
varStack();
if (this.stack.size() == 1)this.roottag = temp.tag;
}
else if (endTag(this.xml[0])) {
this.stack.delete(0); //would be good here to check it's removing the correct end tag.
}
else {
if (temp.tag == "index")
makevar("object."@varStack()).add(this.xml[0].substring(this.xml[0].pos(">")+1,(this.xml[0].pos("</"))-(this.xml[0].pos(">")+(">").length())));
else {
vs = varStack();
if (vs == "")
object.(@temp.tag) = this.xml[0].substring(this.xml[0].pos("<"@[email protected]">")+("<"@[email protected]">").length(),(this.xml[0].pos("</"))-(this.xml[0].pos("<"@[email protected]">")+("<"@[email protected]">").length()));

else
makevar("object."@[email protected]"."@temp.tag) = this.xml[0].substring(this.xml[0].pos("<"@[email protected]">")+("<"@[email protected]">").length(),(this.xml[0].pos("</"))-(this.xml[0].pos("<"@[email protected]">")+("<"@[email protected]">").length()));

}

}
this.xml.delete(0);
}
}

function varStack() {
temp.res = "";
for(s: this.stack) {
if (s != this.roottag) {
if (temp.res == "") temp.res = s;
else temp.res = s @ "." @ temp.res;
}
}
return temp.res;
}

function endTag(line) {
temp.tag = getTagName(line);
return temp.tag.starts("/");
}
function startTag(line) {
temp.tag = getTagName(line);
if (temp.tag.starts("/")) return false;
else if (line.pos("<"@[email protected]">") >= 0 && line.pos("</"@[email protected]">") == -1) return true;
}
function getTagName(line) {
if (line.pos("<") >= 0 && line.charat(line.pos("<")+1) != '?') {
temp.open = line.pos("<");
temp.close = line.pos(">");
for (i = temp.open; i <= temp.close; i++) {
if (line.charat(i) == ' ') { temp.close = i; break; }
}
if ((temp.space < temp.close) && (temp.space > temp.open)) {
temp.close = temp.space;
}
return line.substring(temp.open+1,temp.close-temp.open-1);
}
}


usage:

readXML(xml file, object);
//e.g.
readXML("JkWhoSaysNi.xml",findplayer("JkWhoSaysNi"));


The object is sent to the function like that because for objects like player you can't do player = readXML(file) because player itself is not writable like that. It would be possible to have a more OO approach though using something like player.readXML(file); but do what you want with the code, it wouldn't be hard to change it.

There are some restrictions. It won't read just any XML file. The XML file has to:
Have start and end tags for objects on their own lines e.g.

//wont work:
<player><weapons>...</weapons></player>

//will work:
<player>
<weapons>
...
</weapons>
</player>


It would be possible to remove this restriction but it would require looping through the characters on each line and it would be much less efficient. This script is only really designed to import XML files that have been created using my exporter anyway.

There is also no error checking. An invalid XML file will get parsed incorrectly and not produce the object you want.

Enjoy!
-Knight

JkWhoSaysNi
06-25-2007, 08:42 PM
Ok, i thought it worked but it doesn't for some reason this wont work:


r = "something.test";
object.(@r).foo = "Test";


For some reason it thinks there are dots in the var name. :( so something.test is listed as a variable in getVarNames() of object.

Strange. Any ideas?

Tolnaftate2004
06-25-2007, 08:52 PM
Strange. Any ideas?
makevar.

JkWhoSaysNi
06-25-2007, 09:37 PM
thanks i updated the script in the first post:)

Chompy
06-25-2007, 11:31 PM
Ok, i thought it worked but it doesn't for some reason this wont work:


r = "something.test";
object.(@r).foo = "Test";


For some reason it thinks there are dots in the var name. :( so something.test is listed as a variable in getVarNames() of object.

Strange. Any ideas?

object.(@ r @ ".foo") = "Test";

Would work I think,
but I would say use makevar as Twinny stated

JkWhoSaysNi
06-26-2007, 01:07 AM
Yeah, i already fixed it :)

Here's an example:

Test.xml

<?xml version="1.0">
<object>
<stringvar>test</stringvar>
<intvar>55</intvar>
<objvar>
<intvar1>12</intvar1>
<intvar2>15</intvar2>
<stringvar>test2</stringvar>
<obj2>
<testvar>foo</testvar>
<arrayvar>
<index id="1">3</index>
<index id="2">9</index>
<index id="3">1</index>
</arrayvar>
</obj2>
</objvar>
</object>


example usage


foo = new TStaticVar();
readXML("levels/test.xml",foo);
echo(foo.objvar.obj2.testvar); //echos foo to RC.

Inverness
06-26-2007, 03:19 AM
Maybe you could make the tag names customizable so one could shorten the file?

tagname_object=obj
tagname_stringvar=v1
tagname_intvar=v0
tagname_objvar=v2
tagname_arrayvar=v3

It would use those entries for the tag names then, do you understand?

JkWhoSaysNi
06-26-2007, 03:24 AM
it would be possible, you'd just need 2 arrays, one with names and one with shortened names then have the import/export function look up the shortened/full var name

Although it wont really make that much difference. For simplicities sake it's easier to use the graal var names as the tag names and the problem with that is that you can only import/export specific objects.

My XML file was just an example. You could make any XML file you wanted (provided you had the start and end tags on their own lines for objects) with the tags you wanted, of course the variable names when the file was imported would be the tag names from the file.

cbk1994
07-04-2007, 05:04 AM
What is the advantage of saving vars in XML versus just savevars and loadvars?

JkWhoSaysNi
07-04-2007, 05:08 AM
it will save/load any sub objects recursively.

zokemon
07-09-2007, 05:28 PM
I don't see why they need their own lines...
You could easily loop it all through a string.pos("<") check which isn't every character at all.