2019-01-30 06:36:56 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Xml;
|
|
|
|
|
|
2019-02-01 17:19:20 +00:00
|
|
|
|
namespace RobloxFiles.XmlFormat
|
2019-01-30 06:36:56 +00:00
|
|
|
|
{
|
|
|
|
|
static class XmlDataReader
|
|
|
|
|
{
|
|
|
|
|
public static void ReadProperties(Instance instance, XmlNode propsNode)
|
|
|
|
|
{
|
|
|
|
|
if (propsNode.Name != "Properties")
|
|
|
|
|
throw new Exception("XmlDataReader.ReadProperties: Provided XmlNode's class should be 'Properties'!");
|
|
|
|
|
|
|
|
|
|
foreach (XmlNode propNode in propsNode.ChildNodes)
|
|
|
|
|
{
|
|
|
|
|
string propType = propNode.Name;
|
|
|
|
|
XmlNode propName = propNode.Attributes.GetNamedItem("name");
|
|
|
|
|
|
|
|
|
|
if (propName == null)
|
|
|
|
|
throw new Exception("XmlDataReader.ReadProperties: Got a property node without a 'name' attribute!");
|
|
|
|
|
|
|
|
|
|
IXmlPropertyToken tokenHandler = XmlPropertyTokens.GetHandler(propType);
|
|
|
|
|
|
|
|
|
|
if (tokenHandler != null)
|
|
|
|
|
{
|
|
|
|
|
Property prop = new Property();
|
|
|
|
|
prop.Name = propName.InnerText;
|
|
|
|
|
prop.Instance = instance;
|
|
|
|
|
|
|
|
|
|
if (!tokenHandler.ReadToken(prop, propNode))
|
|
|
|
|
Console.WriteLine("XmlDataReader.ReadProperties: Could not read property: " + prop.GetFullName() + '!');
|
|
|
|
|
|
|
|
|
|
instance.AddProperty(ref prop);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("XmlDataReader.ReadProperties: No IXmlPropertyToken found for property type: " + propType + '!');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Instance ReadInstance(XmlNode instNode, ref Dictionary<string, Instance> instances)
|
|
|
|
|
{
|
|
|
|
|
// Process the instance itself
|
|
|
|
|
if (instNode.Name != "Item")
|
|
|
|
|
throw new Exception("XmlDataReader.ReadItem: Provided XmlNode's class should be 'Item'!");
|
|
|
|
|
|
|
|
|
|
XmlNode classToken = instNode.Attributes.GetNamedItem("class");
|
|
|
|
|
if (classToken == null)
|
|
|
|
|
throw new Exception("XmlDataReader.ReadItem: Got an Item without a defined 'class' attribute!");
|
|
|
|
|
|
|
|
|
|
Instance inst = new Instance(classToken.InnerText);
|
|
|
|
|
|
2019-02-01 17:19:20 +00:00
|
|
|
|
// The 'referent' attribute is optional, but should be defined if a Ref property needs to link to this Instance.
|
2019-01-30 06:36:56 +00:00
|
|
|
|
XmlNode refToken = instNode.Attributes.GetNamedItem("referent");
|
|
|
|
|
|
|
|
|
|
if (refToken != null && instances != null)
|
|
|
|
|
{
|
|
|
|
|
string refId = refToken.InnerText;
|
2019-02-01 17:19:20 +00:00
|
|
|
|
|
2019-01-30 06:36:56 +00:00
|
|
|
|
if (instances.ContainsKey(refId))
|
|
|
|
|
throw new Exception("XmlDataReader.ReadItem: Got an Item with a duplicate 'referent' attribute!");
|
|
|
|
|
|
|
|
|
|
instances.Add(refId, inst);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Process the child nodes of this instance.
|
|
|
|
|
foreach (XmlNode childNode in instNode.ChildNodes)
|
|
|
|
|
{
|
|
|
|
|
if (childNode.Name == "Properties")
|
|
|
|
|
{
|
|
|
|
|
ReadProperties(inst, childNode);
|
|
|
|
|
}
|
|
|
|
|
else if (childNode.Name == "Item")
|
|
|
|
|
{
|
|
|
|
|
Instance child = ReadInstance(childNode, ref instances);
|
|
|
|
|
child.Parent = inst;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return inst;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|