<?xml version="1.0" encoding="UTF-8"?>
<dialogs>
<dialog id="2">
<npcText>Hallo, ich bin Melissa</npcText>
<option id = "0">
<optionText>Hallo.</optionText>
<link>3</link>
</option>
<option id = "1">
<optionText>End</optionText>
<link>9999</link>
</option>
</dialog>
<dialog id="3">
<npcText>Schön dich in dieser Stadt zu sehen.</npcText>
<option id = "0">
<optionText>Ich schaue mich mal um</optionText>
<link>9999</link>
</option>
</dialog>
</dialogs>
My arrays:
DialogNode[] dialogs; // store all dialogs
int[] dialogOptions; // this should store the amount of options for each dialog
I can parse them, my DialogManager works with them. This is all fine. And IF I’m preset the size of the arrays (dialog and options array), it work’s fine too.
My Problem: I want find the appropiate size of both arrays, which I’m need.
My approach:
Read the XML-File and count all dialogs (assumed in my is a amount of options).
Read the XML-File again and read amount of options and store them in my second array (size of array is set by amount of dialogs)
dialogs = new DialogNode[dialogCount];
for(int i = 0; i < dialogCount; i++){
dialogs *= new DialogNode();*
dialogs_.options = new Option[optionsCount*]; for(int x = 0; x < optionsCount;x++){ dialogs.options = new Option(); } }* After this, read the xml-file again and store all data in the right variable of the array. Sorry, is my idea bad? I don’t want to parse the XML more than one time. I want to store all stuff, what I need in this XML. And in don’t want to preset my amount of dialogs and my amount of options for each dialog in the inspector. Greetings, V4mpy_
IMO you should use dynamic arrays for that. In pseudo code:
while (thereisstillsomethingtoreadoutofxml) {
dialogs.changesize(dialogs.length+1);
dialogs[dialogs.length-1].something1 = xmlobject.getnode("something1") // putting something1 into dialogs.something1
}
This way you also decreasing amount of loops to just one as you are reading and increasing array size as needed. Dialogs of course should be arrays of structs that closely mirrors structure of your xml file.
You could just use the XML serializer which handles this stuff for you, here is a helper class:
using UnityEngine;
using System.Collections;
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System;
public static class XmlSupport
{
public static T DeserializeXml<T> (this string xml) where T : class
{
if( xml != null ) {
var s = new XmlSerializer (typeof(T));
using (var m = new MemoryStream (Encoding.UTF8.GetBytes (xml)))
{
return (T)s.Deserialize (m);
}
}
return null;
}
public static object DeserializeXml(this string xml, Type tp)
{
var s = new XmlSerializer (tp);
using (var m = new MemoryStream (Encoding.UTF8.GetBytes (xml)))
{
return s.Deserialize (m);
}
}
public static string SerializeXml (this object item)
{
var s = new XmlSerializer (item.GetType ());
using (var m = new MemoryStream())
{
s.Serialize (m, item);
m.Flush ();
return Encoding.UTF8.GetString (m.GetBuffer ());
}
}
}
Then you mark up your classes, here’s an example of mine:
using System;
using System.Xml.Serialization;
[Serializable]
[XmlRoot("response")]
public class HighScoreResult
{
public static HighScoreResult Create(string xml)
{
return xml.DeserializeXml<HighScoreResult>();
}
public class HighScoreEntry
{
[XmlElement]
public int position;
[XmlElement]
public int score;
[XmlElement("screenname")]
public string playerName = "";
}
public class HighScoreTableResult
{
[XmlElement]
public string name;
[XmlElement]
public int position;
[XmlElement]
public int score;
[XmlArray("highscoreentries")]
[XmlArrayItem("highscoreentry")]
public HighScoreEntry[] highscoreentries = new HighScoreEntry[0];
}
public class HighScore
{
[XmlArray("highscoretables")]
[XmlArrayItem("highscoretable")]
public HighScoreTableResult[] highscoretables = new HighScoreTableResult[0];
}
[XmlElement]
public HighScore highscore;
}
Then you deserialize one like this:
var result = someXmlString.DeserializeXml<HighScoreResult>();
And serialize it using:
var xml = someXmlSerializableObject.SerializeXml();