} // 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()
예제 #2
0
        }//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()