using System; using System.Collections.Generic; using System.Xml; namespace RobloxFiles.XmlFormat { public 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, XmlRobloxFile file = null) { // Process the instance itself if (instNode.Name != "Item") throw new Exception("XmlDataReader.ReadInstance: Provided XmlNode's name should be 'Item'!"); XmlNode classToken = instNode.Attributes.GetNamedItem("class"); if (classToken == null) throw new Exception("XmlDataReader.ReadInstance: Got an Item without a defined 'class' attribute!"); Instance inst = new Instance(classToken.InnerText); // The 'referent' attribute is optional, but should be defined if a Ref property needs to link to this Instance. XmlNode refToken = instNode.Attributes.GetNamedItem("referent"); if (refToken != null && file != null) { string refId = refToken.InnerText; if (file.Instances.ContainsKey(refId)) throw new Exception("XmlDataReader.ReadInstance: Got an Item with a duplicate 'referent' attribute!"); file.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, file); child.Parent = inst; } } return inst; } } }