- Home /
XML Serializer not deserializing past second class
Heya everyone, I've been working a class that's supposed to Deserialize my scene's dialog from an XML file. This is done by having a "SceneDialog", containing a list of "Dialog"s, which contains a list of "DialogLine"s, which contains a list of "Response"s. (SceneDialogs > Dialog > DialogLine > Response). However, while it correctly serializes SceneDialogs and a list of Dialogs, it stops there and doesn't add the list of DialogLines to the Dialog.
This is the class the deserializes the xml-file; this seems to work perfectly fine.
public static T Deserialize<T> (string path) {
XmlSerializer serializer = new XmlSerializer (typeof(T));
StreamReader reader = new StreamReader (path);
T deserialized = (T)serializer.Deserialize (reader.BaseStream);
reader.Close ();
return deserialized;
}
The following Lines call the Deserialize () function, and the classes the data is supposed to be stored in.
//Some stuff to check if the file path is valid
if (File.Exists (Path.Combine (Application.dataPath, xmlPath))) {
sceneDialogs = XML_Loader.Deserialize <SceneDialogs> ((Path.Combine (Application.dataPath, xmlPath)));
} else {
Debug.LogError ("XML File: " + (Path.Combine (Application.dataPath, xmlPath)) + " is not found.");
}
[XmlRoot ("SceneDialogs")]
[XmlInclude(typeof(Dialog))]
[XmlInclude(typeof(DialogLine))]
[XmlInclude(typeof(Response))]
public class SceneDialogs {
[XmlArray("RandomNode"), XmlArrayItem("Dialog")]
public List<Dialog> allDialogsInScene;
}
[XmlType ("Dialog")]
public class Dialog {
[XmlAttribute ("ID")]
public int ID;
[XmlArray("Dialog"), XmlArrayItem("DialogLine")]
public List <DialogLine> DialogLines;
}
[XmlType ("DialogLine")]
public class DialogLine {
[XmlAttribute ("lineID")]
public int lineID;
[XmlElement ("DialogText")]
public string text;
[XmlArray("DialogLine"), XmlArrayItem("Response")]
public List <Response> responses;
}
[XmlType ("Response")]
public class Response {
[XmlAttribute ("responseID")]
public int responseID;
[XmlElement ("ResponseText")]
public string text;
[XmlElement ("FollowUpLine")]
public int followupLine;
}
As for the actual XML file in question:
<?xml version="1.0" encoding="UTF-8"?>
<SceneDialogs>
<RandomNode>
<Dialog ID='0000'>
<DialogLine lineID='0'>
<DialogText> "Stay a while and listen." </DialogText>
<Response responseID='0'>
<ResponseText> "Okay." </ResponseText>
<FollowUpLine> '1' </FollowUpLine>
</Response>
<Response responseID='1'>
<ResponseText> "No." </ResponseText>
<FollowUpLine> '-1' </FollowUpLine>
</Response>
</DialogLine>
<DialogLine lineID='1'>
<DialogText> "Once upon a time, I was like... the main character of this scene." </DialogText>
<Response responseID='0'>
<ResponseText> "Wow, that's amazing!." </ResponseText>
<FollowUpLine> '3' </FollowUpLine>
</Response>
<Response responseID='1'>
<ResponseText> "I don't believe you." </ResponseText>
<FollowUpLine> '-1' </FollowUpLine>
</Response>
</DialogLine>
</Dialog>
</RandomNode>
</SceneDialogs>
![alt text][1] [1]: /storage/temp/120002-errormessage.png
As you can see, it correctly identifies and creates the SceneDialogs, and places one Dialog in it with the correct ID. It does not, however add any of the DialogLines into the Dialog's List (the count stays 0). To add to this, the entire XmlSerializer is kind of a blackbox, which does something but there's no real method of tracking what's going on inside. So, if anyone has any idea on what is going wrong and how to fix it I would greatly appreciate it. Thank you in advance.
Hey I don't know xlm deserialize, but does it related with this ?: https://stackoverflow.com/questions/25243942/serialize-to-xml-a-class-containing-a-struct .
Because not working children are struct.
Heya, thanks for the reply. I have honestly no idea how I managed to not notice they were structs during the many hours I've spent staring at this code so far. However, changing them to classes still grants the same result.
Do you think the accessibility might be an issue? It doesn't seem to cause issues for the SceneDialogs and Dialog classes, however, that subject has always been a bit hazy for me. :D
[XmlArray("DialogLine"), XmlArrayItem("DialogLine")] is this line ok?
Answer by Bunny83 · Jul 02, 2018 at 07:51 PM
Well, the problem here is that you declared your "DialogLines" List as XmlArray. However in your XML there is no element called "DialogLine" that contains "DialogLine" elements. Your "Dialog" directly contains the DialogLine elements. Usually you just want to replace your XmlArray and XmlArrayItem with just an XmlElement
[XmlElement("DialogLine")]
public List <DialogLine> DialogLines;
Whenever you use XmlArray / XmlArrayItem the serializer / deserializer expects a seperate grouping element which name is either specified in the XmlArray attribute or if no name is specified the name of the list is used.
You had the same problem with your Dialogs where you inserted your "RandomNode" (which should be named just "Dialogs" or if not specifying a name it would use "allDialogsInScene" as grouping element name). So you could remove the "RandomNode" entirely and just declare your root element like this:
public class SceneDialogs {
[XmlElement("Dialog")]
public List<Dialog> allDialogsInScene;
}
Have a look at this SO question for reference.
Note the same is true for your Responses:
[XmlElement("Response")]
public List <Response> responses;
That totally worked, which is a bit confusing since I think every example I've seen used the whole Array/ArrayItem thing. Thank you so much for your help and the descriptive explanation. I've spent hours and hours on this, and have been close to giving up for a while now; so you really saved me here.
It now throws an "FormatException: Input string was not in the correct format" on the Response contents (not the actual Response itself), so I'll have to go figure out how to fix that. :P
The problem is probably your quotation marks inside your content. It should be something like this:
<ResponseText>Wow, that's amazing!.</ResponseText>
<FollowUpLine>3</FollowUpLine>
Your answer
Follow this Question
Related Questions
How to Shortly Reset a XML File and Class VariablesTo Create New Game 0 Answers
Invalid Encoding Specification Xml 1 Answer
Read AND Write to XML at runtime 1 Answer
XML Serializable "if" 1 Answer
Loading Xml file issues 0 Answers