} // TryReadNext() // // // // ***************************************************************** // **** Create Node() **** // ***************************************************************** private bool TryCreateNode(string tagName, ref Dictionary <string, string> attributes, bool createNode, out IStringifiable newNode) { newNode = null; Type objectType; if (createNode) { newNode = new Node(tagName, attributes); } else if (Stringifiable.TryGetType(tagName, out objectType)) { newNode = null; System.Reflection.MethodInfo methodInfo = objectType.GetMethod("GetInstance"); if (methodInfo != null && methodInfo.IsStatic) { newNode = (IStringifiable)methodInfo.Invoke(null, new object[0] { }) as IStringifiable; // create object using GetInstance() } else { newNode = (IStringifiable)Activator.CreateInstance(objectType) as IStringifiable; // create object via constructor. } if (newNode != null) { newNode.SetAttributes(attributes); } } else { // TODO: Throw exception?! throw new Exception("Unknown object type."); //return false; } return(true); }// CreateNode()
}//Stringify(). // // private void Stringify(int level, ref StringBuilder s) { // Nice to read indenting for elements. if (level > 0) { s.Append("\r\n"); } for (int i = 0; i < level; ++i) { s.Append(" "); } // Starting tag: s.AppendFormat("<{0}", this.Name); foreach (string attributeKey in this.Attributes.Keys) { s.AppendFormat(" {0}={1}", attributeKey, this.Attributes[attributeKey]); } // sub-Elements if (this.SubElements == null || this.SubElements.Count > 0) { s.Append(">"); foreach (IStringifiable element in this.SubElements) { if (element is Node) { ((Node)element).Stringify(level + 1, ref s); } else { s.AppendFormat("{0}", Stringifiable.Stringify(element)); } } // Ending tag s.AppendFormat("</{0}>", this.Name); } else { // If there are no sub elements we can use the "complete" tag format for this object. s.Append("/>"); } }// Stringify()
// // // ******************************************************************* // **** Try Read Next() **** // ******************************************************************* /// <summary> /// Method attempts to read (as much XML as needed to create) the next ISerializable object in file stream. /// This methoc can be called repeatedly to obtain each successive object in file. Returns a false at the end /// of the file stream. /// TODO: Implement reflective object creation. /// </summary> /// <param name="newObject">Newly created object</param> /// <param name="createNode">If call is to create stand-in pseudo node object in place of real one.</param> /// <returns>True signifies sucessful creation of one object, false if at end of file.</returns> public bool TryReadNext(out IStringifiable newObject, bool createNode = false) { newObject = null; List <IStringifiable> parentNodes = new List <IStringifiable>(); // each time a new instrument is created, we move down another level of depth. IStringifiable aNode = null; string tagName; TagType tagType; Type objectType; Dictionary <string, string> attributes = new Dictionary <string, string>(); while (TryReadNextTag(out tagName, out tagType, ref attributes)) { switch (tagType) { case TagType.StartTag: if (!TryCreateNode(tagName, ref attributes, createNode, out aNode)) { return(false); } if (parentNodes.Count > 0) { parentNodes[parentNodes.Count - 1].AddSubElement(aNode); // Connect this node to it's parent node. } parentNodes.Add(aNode); // Push this object onto parent list, in case we next read a child object. break; case TagType.EndTag: aNode = parentNodes[parentNodes.Count - 1]; // Get the current parent node if (createNode && tagName == ((Node)aNode).Name) // { parentNodes.RemoveAt(parentNodes.Count - 1); // pop out last, since we finished it } else if (Stringifiable.TryGetType(tagName, out objectType) && tagName.Equals(objectType.FullName)) { parentNodes.RemoveAt(parentNodes.Count - 1); // pop out last, since we finished it } else { // Error! Throw exception? return(false); } // Check exit condition. if (parentNodes.Count == 0) { newObject = aNode; return(true); } break; case TagType.CompleteTag: if (!TryCreateNode(tagName, ref attributes, createNode, out aNode)) { return(false); } if (parentNodes.Count == 0) // Check exit condition { newObject = aNode; return(true); // This zero-depth object is complete! We are done! } else { parentNodes[parentNodes.Count - 1].AddSubElement(aNode); // connect this to its parent. } break; case TagType.Comment: break; case TagType.None: break; default: break; }// tagType // attributes.Clear(); } // wend parentNodes = null; newObject = null; return(false); } // TryReadNext()