Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Introduction to NIEM and IEPDs

, , 1 Jan 2009 CPOL
Developed by the Department of Justice and the Department of Homeland Security, the National Information Exchange Model "Bridges Information Systems".
IepdBrowser.zip
IepdBrowser
bin
Debug
Clifton.Tools.Strings.dll
Clifton.Tools.Strings.pdb
IepdBrowser.exe
IepdBrowser.pdb
IepdBrowser.vshost.exe
IepdBrowser.vshost.exe.manifest
IepdParser.vshost.exe.manifest
CVS
Entries
Entries.Extra
Entries.Extra.Old
Entries.Old
Repository
Root
obj
Debug
IepdBrowser.csproj.GenerateResource.Cache
IepdBrowser.exe
IepdBrowser.IepdBrowserForm.resources
IepdBrowser.pdb
IepdBrowser.Properties.Resources.resources
IepdParser.csproj.GenerateResource.Cache
Refactor
ResolveAssemblyReference.cache
TempPE
Properties.Resources.Designer.cs.dll
Properties
CVS
Entries
Entries.Extra
Entries.Extra.Old
Entries.Old
Repository
Root
Settings.settings
// (c) 2009 Marc Clifton
// All Rights Reserved.
// You are free to use this code as long as you comply with the
// Code Project Open License (CPOL) 1.02
// http://www.codeproject.com/info/cpol10.aspx

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Schema;

namespace IepdBrowser
{
	public partial class IepdBrowserForm : Form
	{
		protected Iepd iepd;

		public IepdBrowserForm()
		{
			InitializeComponent();
		}

		public void PopulateTree()
		{
			tnTypes.Nodes.Clear();
			tvElements.Nodes.Clear();
			dgvLookupData.DataSource = null;

			Dictionary<QName, List<XmlSchemaType>> h = iepd.TypeHierarchy;

			foreach (KeyValuePair<QName, List<XmlSchemaType>> kvp in h)
			{
				// Find all nodes that are root parents.

				if (!iepd.ParentList.ContainsKey(kvp.Key))
				{
					TreeNode tn;
					tn = new TreeNode(kvp.Key.name);
					tn.Tag = kvp.Key;
					tnTypes.Nodes.Add(tn);
					PopulateChildren(iepd, tn, kvp.Key);
				}
			}

			tnTypes.Sort();
			tnTypes.ExpandAll();					   
		}

		protected void PopulateChildren(Iepd iepd, TreeNode tn, QName qname)
		{
			if (iepd.TypeHierarchy.ContainsKey(qname))
			{
				foreach (XmlSchemaType xst in iepd.TypeHierarchy[qname])
				{
					TreeNode tnChild = new TreeNode(xst.QualifiedName.Name);
					tnChild.Tag = new QName(xst.QualifiedName);
					tn.Nodes.Add(tnChild);
					PopulateChildren(iepd, tnChild, new QName(xst.QualifiedName.Name, xst.QualifiedName.Namespace));
				}
			}
		}

		protected void tnTypes_AfterSelect(object sender, TreeViewEventArgs e)
		{
			QName qname = (QName)e.Node.Tag;
			tbNamespace.Text = qname.ns;

			tvElements.Nodes.Clear();
			Cursor = Cursors.WaitCursor;
			List<ElementInfo> elInfoList = iepd.GetElements(qname);
			TreeNode tnRoot = new TreeNode("Elements");

			foreach (ElementInfo elInfo in elInfoList)
			{
				TreeNode tn = CreateElementRow(elInfo);
				tnRoot.Nodes.Add(tn);
			}

			tvElements.Nodes.Add(tnRoot);

			tnRoot.Expand();
			Cursor = Cursors.Arrow;
		}

		protected TreeNode CreateElementRow(ElementInfo elInfo)
		{
			TreeNode tn = new TreeNode();
			string cardinality = BuildCardinalityString(elInfo);
			tn.Text = elInfo.Name + " " + cardinality + ", Type=" + elInfo.Type + ")";
			tn.Tag = elInfo;

			if (elInfo.ChildElements.Count > 0)
			{
				foreach (ElementInfo ei in elInfo.ChildElements)
				{
					TreeNode tnChild = CreateElementRow(ei);
					tn.Nodes.Add(tnChild);
				}
			}
			else
			{
				// If we haven't filled in the child elements, see if there are any and create a placeholder.
				// This puts a "+" sign on the node, so when the user opens it, we can get the child elements
				// at that point.  The purpose of this is to improve the UI response when selecting a type,
				// because some of the types can take quite a while to generate the complete hierarchy.
				if (iepd.HasChildElements(elInfo))
				{
					TreeNode tnChild = new TreeNode("More...");
					tn.Nodes.Add(tnChild);
				}
			}

			List<SubstElementsInfo> substGroupList = elInfo.SubstGroupElements;

			foreach (SubstElementsInfo substElementInfo in substGroupList)
			{
				TreeNode tnsg = new TreeNode();
				// Set to non-null, so it's not deleted when we collapse and then drill into an element
				// that only has one substitution group.  The tag is not currently used (2/
				tnsg.Tag = elInfo;
				tnsg.Text = "Substitution Group (";
				// tnsg.Text += substElementInfo.xseSubstGroup.Name;
				tnsg.Text += substElementInfo.xseSubstGroup.QualifiedName;
				tnsg.Text += ")";
				tn.Nodes.Add(tnsg);

				foreach (ElementInfo sgElemInfo in substElementInfo.substElements)
				{
					TreeNode sgSubNode = CreateElementRow(sgElemInfo);
					tnsg.Nodes.Add(sgSubNode);
				}
			}

			return tn;
		}

		protected string BuildCardinalityString(ElementInfo elInfo)
		{
			StringBuilder sb = new StringBuilder();
			sb.Append("(");

			if (elInfo.MinOccurs.ToLower() == "unbounded")
			{
				sb.Append("*");
			}
			else
			{
				sb.Append(elInfo.MinOccurs);
			}

			sb.Append("..");

			if (elInfo.MaxOccurs.ToLower() == "unbounded")
			{
				sb.Append("*");
			}
			else
			{
				sb.Append(elInfo.MaxOccurs);
			}

			sb.Append(")");

			return sb.ToString();
		}

		private void mnuOpen_Click(object sender, EventArgs e)
		{
			OpenFileDialog ofd = new OpenFileDialog();
			ofd.Filter = "schema files (*.xsd)|*.xsd";
			ofd.RestoreDirectory = true;
			DialogResult res = ofd.ShowDialog();

			if (res == DialogResult.OK)
			{
				iepd = new Iepd(ofd.FileName);
				iepd.BuildTypeHierarchyFromElements();
				PopulateTree();
			}
		}

		private void mnuExit_Click(object sender, EventArgs e)
		{
			Close();
		}

		private void tvElements_AfterSelect(object sender, TreeViewEventArgs e)
		{
			ElementInfo elInfo = (ElementInfo)e.Node.Tag;
			List<EnumFacet> lookupList = iepd.GetLookupData(elInfo);
			dgvLookupData.DataSource = lookupList;
		}

		private void tvElements_BeforeExpand(object sender, TreeViewCancelEventArgs e)
		{
			ElementInfo elInfo = (ElementInfo)e.Node.Tag;

			// A "More..." child node will have Tag==null
			// There may be more than one child node, 
			// as the node may contain "More..." plus substitution groups.
			if ( (e.Node.Nodes.Count > 0) && (e.Node.Nodes[0].Tag==null) )
			{
				// Remove the "More..." node.
				e.Node.Nodes[0].Remove();
				elInfo.DrillIntoType(iepd);
				int n = 0;

				foreach (ElementInfo ei in elInfo.ChildElements)
				{
					TreeNode tnChild = CreateElementRow(ei);
					e.Node.Nodes.Insert(n, tnChild);
					++n;
				}
			}

			e.Cancel = false;
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Authors

Marc Clifton

United States United States
Marc is the creator of two open source projets, MyXaml, a declarative (XML) instantiation engine and the Advanced Unit Testing framework, and Interacx, a commercial n-tier RAD application suite.  Visit his website, www.marcclifton.com, where you will find many of his articles and his blog.
 
Marc lives in Philmont, NY.

Mark Long
Database Developer
United States United States
Educated in industrial engineering, optimization techniques, information security, computer science, math, statistics, and business management, I support a public safety software platform.
 
Keywords:
Information Systems, relational database management systems, information security, ERP, EAI, SAP, PeopleSoft, data warehousing, OFX, e-commerce, speech recognition, CRM, statistical analysis, modeling and simulation, operations research, cognitive engineering.

| Advertise | Privacy | Mobile
Web02 | 2.8.141022.1 | Last Updated 1 Jan 2009
Article Copyright 2009 by Marc Clifton, Mark Long
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid