- Home /
The question is answered, right answer was accepted
Reading data from xml.
I have been through the many questions and answers on how to read data from an xml file. But it is not sinking in. I need to understand what is happening. I can currently read the info I need from a plain text file, but it is cumbersome (possibly not doing that correctly anyway). I thought using an xml file would be better. I need to read the data, to help construct a level. This should be very simple for someone who knows what they are doing.
My scenario: I want to make a grid at runtime. The data is stored in an xml file. It has Level Name which I want to be an int (1). It has a minimum value, aslo and int. It has grid size, and int. (will be used twice but all boards are square) then it has a series of 0,1 to denote a particular position, needs to be an array of ints,
Here is the xml.
<levels>
<level>
<name>1</name>
<minimum>2</minimum>
<size>3</size>
<array>010010001</array>
</level>
</levels>
This is stored in Assets/Resources so I can use Resources.Load. I would like to be able to keep all the level(s) into in this one file (instead of 120 different files. They would all contain the exact same info (different values). Anybody want to take a crack at reading 3 ints, and an array of ints from this xml?
Happy $$anonymous$$onday morning! $$anonymous$$aybe someone can help today.
Answer by CodeElemental · Mar 17, 2014 at 02:19 PM
I guess you can try using standard .Net xml parsing (for deserialization).
public TextAsset textFile;
// Load xml document from Textasset
XmlDocument xmlDoc = new XmlDocument();
string xml = textFile.text;
xmlDoc.LoadXml(xml);
// xmldocument is loaded.
// start parsing.
string levelsxpath = "levels/level";
XmlNodeList nodes = xmlDoc.SelectNodes(levelsxpath);
for (int i = 0; i < nodes.Count; i++)
{
string levelname = nodes[i].SelectNode("name").value;
int minimum = Convert.ToInt32(nodes[i].SelectNode("minimum").value);
}
Find out more here.
Will this not result in
levelname = 010010001
$$anonymous$$imum = 010010001
If seems for each i in nodes, it will assign the value for levelname and $$anonymous$$imum, every time. So when the loop is done, levelname will be a string 010010001, and $$anonymous$$imum will be an int 010010001.
I know this is just an example, but it seems that this method is not different from reading a plain text file. I will still need a separate file for each level.
Right now, my text file looks like this.
Level1 $$anonymous$$in2 Size33 010010001
I grab each value by its index
int level = Convert.ToInt32(asset.text[5]) -48;
int $$anonymous$$imum = Convert.ToInt32(asset.text[12] - 48;
int gridWidth = Convert.ToInt32(asset.text[20]) - 48;
int gridHeight = gridWidth;
for(int i = 27; i<asset.text.Length;i++){
int position = Convert.ToInt32(asset.text[i])-48;
if(position = 0){
//Do stuff
}
else{
//Do the other stuff
}
}
I had to subtract 48 since the conversion from ANSI string to int: well, 0 is 48 when converted. 1 is 49, etc.
Yeah sorry for the typo, it was meant as a general guideline not specific solution.
This script iterates through all the level nodes and accesses them via xpath, so this solves your "reading the xml" problem
If you want to convert the array (represented by a string "010010001" into a byte[] , you can get the chars of the string and compare them with '1' or '0' so you know what byte to generate. This solves your "reading the array" problem.
The way i understand you have the data xml alredy and you just use it to generate the grid at runtime , right ?
I have the one example data.xml. And yes, it is going to be used to generate a grid (more complex, but same general concept). The 'grid' is for a puzzle game. It will have a $$anonymous$$imum number of moves, a width and height, and each section will have one of two possible positions (0 or 1). I was hoping that an xml file would be faster, would require less conversion, and would allow me to keep all level data (at least 120 levels) in one single file. I did not want to have to manage 120 separate files. What if I needed to change one thing, I would have to change 120 files. With an xml of all level data, I could just add a child node in each level node. Anyway, the solution above seems like it will work in the same way that my current system does. Thank you for your help, but I was looking for something in a different direction. I think I will hold out for something more. Thanks again.
Also, with xml, I would be able to use the same information to then write an xml file with save data, and statistics.
I don't see why you can't store them in one xml file with my proposal. Something like this :
<levels>
<level>
<name>1</name>
<$$anonymous$$imum>2</$$anonymous$$imum>
<size>3</size>
<array>010010001</array>
</level>
<level>
<name>2</name>
<$$anonymous$$imum>4</$$anonymous$$imum>
<size>2</size>
<array>010010001</array>
</level>
<level>
<name>3</name>
<$$anonymous$$imum>1</$$anonymous$$imum>
<size>2</size>
<array>010010001</array>
</level>
</levels>
However, xml creates a lot of overhead (in this case , for storing small amount of data (int , int , int , array ) it creates structure with a lot of overhead
1 = ( 6-char string + int + 7char string )
So, I recommend using JSON ins$$anonymous$$d of xml in your particular scenario.
Will mark as accepted and look into JSON... since I do not know how to implement that either. But, as you stated, you answer does address "reading xml" and "reading array data". Thanks for you help.
Follow this Question
Related Questions
c# to compile xml string as code during runtime 1 Answer
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Read AND Write to XML at runtime 1 Answer
Questions about XML save/load 0 Answers