|
// (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.
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.