/// <summary>
 /// Create a new PostParseEventArgs object.
 /// </summary>
 public PostParseEventArgs(XmlDataRows data, XmlDocument xml)
 {
     this.Data = data;
     this.Xml  = xml;
 }
        /// <summary>
        /// Parse the xmlfile and process the data it contains.
        /// </summary>
        /// <param name="net">NetManager object to use when downloading xml files
        /// (null if parsing a MetaXmlFile).</param>
        public void Parse(NetManager net)
        {
            MultiExceptionHandler mex = new MultiExceptionHandler();
            string xpathDefaults      = "/" + this.xpath.Split('/')[1] + "/defaults/def";


            // call preparse event handler

            if (this.PreParse != null)
            {
                this.PreParse(this, null);
            }


            // get xml document

            XmlDocument xml;

            if (this is MetaXmlFile)
            {
                xml             = new XmlDocument();
                xml.XmlResolver = null; // disable automatic dtd validation
                xml.Load(((MetaXmlFile)this).LocalFile);
            }
            else
            {
                xml = net.GetXmlDocument(this);
            }


            // parse defaults (if present)

            Dictionary <string, string> xmlDefaults = new Dictionary <string, string>();

            foreach (XmlElement node in xml.SelectNodes(xpathDefaults))
            {
                if (node.HasAttribute("att") && node.HasAttribute("value"))
                {
                    xmlDefaults.Add(node.Attributes["att"].Value, node.Attributes["value"].Value);
                }
            }


            // parse data rows

            XmlDataRows rows = new XmlDataRows(this);

            foreach (XmlElement node in xml.SelectNodes(this.xpath))
            {
                try
                {
                    string[] row = new string[this.attributes.Length];

                    for (int i = 0; i < this.attributes.Length; i++)
                    {
                        string attr = this.attributes[i];

                        if (node.HasAttribute(attr))
                        {
                            row[i] = node.Attributes[attr].Value;
                        }
                        else if (xmlDefaults.ContainsKey(attr))
                        {
                            row[i] = xmlDefaults[attr];
                        }
#if DEBUG
                        else
                        {
                            mex.Add(new ApplicationException(String.Format("Parse {0}: missing attr '{1}'", this.name, attr)));
                        }
#endif
                    }

                    rows.Add(row);
                }
                catch (Exception ex) { mex.Add(ex); }
            }


            // call the postparse event handler

            try
            {
                if (this.PostParse != null)
                {
                    this.PostParse(this, new PostParseEventArgs(rows, xml));
                }
            }
            catch (Exception ex) { mex.Add(ex); }


            // if any errors, throw first

            mex.Throw();
        }