Click here to Skip to main content
Click here to Skip to main content

A Dynamically Generated XML Data Editor

By , 14 Oct 2003
 

Contents

Introduction

My previous utility [^] helped you to create XSD files. After completing this, I hunted around for a utility that would let me manage the data of an associated XML document. Specifically, I wanted two features:

  1. A generic solution that would let me create XML data against any XSD schema
  2. Something that customizes the input control based on schema information

I did not find anything that came close to meeting these two criteria. All of the editors I found were oriented around editing the entire XML document, tags and all, not just the data. For me, the tags are a major encumberance to quickly putting together a data set. Furthermore, the .NET solution, which is to create a CS file, is a complicated, multi-step and non-generic approach.

Thus, I decided to write my own XML data editor and, in the process, learn more about XSD, XML, and XPath. Utilizing the XmlDataDocument, XmlSchema and DataTable classes, I have created a generic editor that dynamically creates specialized controls for data entry, based on the schema definition and table relationships.

An example of the result is: (Sorry about the long picture!)

Screenshot - XmlDataEditor.jpg

...which is derived from the schema (screenshot from my XML Schema Editor):

Screenshot - schema.jpg

Example Files

The download includes an example XSD and XML file. Load the sampleSchema2.XSD file first using the File/Load XSD menu item. Then load the sale5.xml file using the File/Load XML menu item.

Some Background Basics: Importing the Schema and XML Documents

Given:

private XmlSchema schema=null;
private XmlDataDocument doc=null;

The XSD file is loaded:

// get a stream reader for the XSD file
StreamReader tr=new StreamReader(dlgOpen.FileName);
// read the file into the XmlSchema object
schema=XmlSchema.Read(tr, 
  new ValidationEventHandler(SchemaValidationHandler));
tr.Close();
// report any problems with the schema by compiling it
CompileSchema();
// create the document
doc=new XmlDataDocument();
// open the schema again
tr=new StreamReader(dlgOpen.FileName);
// read it into the DataSet member
doc.DataSet.ReadXmlSchema(tr);

The XML file is loaded:

XmlTextReader tr=new XmlTextReader(dlgOpen.FileName);
doc.Load(tr);
tr.Close();

Dynamic GUI Generation

Once the schema has been loaded into the DataSet, the .NET framework automatically creates the associated DataTable objects and their relationships. This information is used to generate the framework for the GUI, which is a series of recursive GroupBox objects encapsulating Control objects, all contained within a panel. The panel provides us with automatic scrolling capabilities, which eleviates the task of managing the scroll functions ourselves.

Get Root Tables

The GUI generation begins by inspecting all root (not parent) tables and determining the XmlSchemaComplexType that defines them. The assumption here is that any root table will be represented in the schema as an element referencing a global complex type.

private void ConstructGUI(DataSet dataSet)
{
  Point pos=new Point(10, 10);
  // get all tables in the dataset
  foreach (DataTable dt in dataSet.Tables)
  {
    // but we're only interested in the toplevel tables
    if (dt.ParentRelations.Count==0)
    {
      /*
       * Rule 1:
       * A top level table will be a top level element in the schema that
       * is of a complex type.  The element name will be the table name.
       * What we want to identify is the complex 
       * type that the table references,
       * so that we can determine the data types of the columns.
       * 
       * Any other rules???
       */
       XmlSchemaElement el=GetGlobalElement(dt.TableName);
       XmlSchemaComplexType ct=GetGlobalComplexType(el.SchemaTypeName.Name);
       Point p2=ConstructGUI(pos.X, pos.Y, dt, pnlDynForm, ct);
       pos.Y+=p2.Y;
       }
    }
}

There are two very simple helper functions to acquire the appropriate objects, illustrated here because of the different mechanism required to obtain them:

GetGlobalElement()

private XmlSchemaElement GetGlobalElement(string name)
{
  XmlQualifiedName qname=new XmlQualifiedName(name, schema.TargetNamespace);
  XmlSchemaObject obj=schema.Elements[qname];
  return obj;
}

GetGlobalComplexType()

private XmlSchemaComplexType GetGlobalComplexType(string name)
{
  for (int i=0; i < schema.Items.Count; i++)
  {
    XmlSchemaComplexType obj=schema.Items[i] as XmlSchemaComplexType;
    if (obj != null)
    {
      if (obj.Name==name)
      {
        return obj;
      }
    }
  }
  return null;
}

Create the GroupBox: A Collection of Records

The GroupBox is created in a straightforward manner, along with a helper hash table called tableInfo. Initially, the group box is not given any size, as this is determined after all the controls have been placed. Also, a navigation bar is created and associated with the group box, providing the first, previous, next, last, new and delete record buttons, as well as the n of m record info text.

private Point ConstructGUI(int absx, int absy, DataTable dt, 
  Control gbParent, XmlSchemaComplexType ct)
{
  GroupBox gb1=new GroupBox();
  gb1.Font=new Font(gb1.Font, FontStyle.Bold);
  gb1.Text=dt.TableName;
  gb1.Location=new Point(absx, absy);
  gb1.Parent=gbParent;
  gb1.Visible=true;

  tableInfo[dt]=new TableInfo();
  CreateRecordNavigationBar(10, 15, gb1, dt);
  ...

Once the group box is placed, the following steps are performed on all columns in the DataTable "dt":

// For each column in the table...
foreach (DataColumn col in dt.Columns)
  {...

1. The placement of the column name and the appropriate control for non-hidden columns:

// if it's not an internal ID...
if (col.ColumnMapping != MappingType.Hidden)
{
  // display its name
  CreateLabel(relx, rely, col.ColumnName, gb1);
  TypeInfo ti=GetTypeInfo(ct, col.ColumnName);
  if (ti != null)
  {
    Control editCtrl=CreateEditControl(relx+120, rely, ti, gb1, dt, col);
  }
}

2. The placement of the column name and read-only text control for hidden fields. This could be omitted, but I left it in so that I could inspect the hidden features of the DataSet. Columns that have relationships with child tables are colored blue and columns that have a relationship with a parent table are colored red (setting the color is not shown here). Because of the nature of schema, these relationships are always 1:1 (as far as I've seen!).

if (col.ColumnMapping==MappingType.Hidden)
{
  Label lbl=CreateLabel(relx, rely, col.ColumnName, gb1);
  Control editCtrl=CreateEditControl(relx+120, 
    rely, new TypeInfo("string"), gb1, dt, col);
  editCtrl.Size=new Size(50, 20);
  ((TextBox)editCtrl).ReadOnly=true;

3. If any child relationships are discovered, the same function is invoked recursively:

// Get child relationships, which are displayed as indented groupboxes
foreach (DataRelation childRelation in dt.ChildRelations)
{
  DataTable dt2=childRelation.ChildTable;
  XmlSchemaElement el2=GetLocalElement(ct, dt2.TableName);
  XmlSchemaComplexType ct2=GetGlobalComplexType(el2.SchemaTypeName.Name);
  if (ct2==null)
  {
    ct2=GetLocalComplexType(el2);
  }
  Point p=ConstructGUI(relx+20, rely+20, dt2, gb1, ct2);

There's also some straightforward math regarding indenting and calculating the size of the outer groupbox, which I'm not going to discuss.

Control Creation

The controls within the group box are created based on some simplistic rules from information gathered from the schema. This area could be greatly expanded because I simply didn't want to implement all the basic types. The rules are as follows:

  1. If the element contains an enumeration, create a ComboBox using the enumeration data.
  2. If the element contains minInclusive and maxInclusive facets, create a NumericUpDown control.
  3. If the element is a Boolean type, create a CheckBox control.
  4. If the element is a decimal or positive integer type, create a right aligned TextBox control.
  5. Everything else is a TextBox control.

Currently, I ignore other facets such as length and pattern.

Record Navigation

Record navigation requires that we manually select child records that are indexed by the parent record ID.

The Basics

These rows are stored in the tableInfo as an array for easy lookup. There are two helper functions that are used extensively. The first adjusts the "record m of n" display for the specified navigator's TextBox. There's a test here to set the position tracker if the table is a root table. This is probably not the best place for this code!

private void UpdateRecordCountInfo(DataTable dt)
{
  // update the text box to reflect the record #
  TableInfo ti=tableInfo[dt] as TableInfo;
  if (dt.ParentRelations.Count==0)
  {
    ti.pos=BindingContext[dt].Position+1;
  }
  ti.tb.Text="   record "+ti.pos.ToString()+" of "+ti.rows.ToString();
}

The GetMatchingRows helper is very useful in determining the child rows that match the parent's ID. Given the child table, the code acquires the parent table and the column that establishes the relationship. It is assumed, rightly so I believe, that there will ever only be one column that defines the relationship. From this, the BindingContext is used to locate the current parent row. Given the parent row, we can acquire the value of the ID and execute a "select" query on the child rows matching the relationship ID.

private int GetMatchingRows(DataTable dt)
{
  TableInfo ti=tableInfo[dt] as TableInfo;
  // get parent relationship
  DataRelation parentRelation=dt.ParentRelations[0];
  // get the parent table
  DataTable dt2=parentRelation.ParentTable;
  // get the parent column (1:1 relationship always)
  DataColumn dcParent=parentRelation.ParentColumns[0];
  // get the current record # of the parent
  int n=BindingContext[dt2].Position;
  if (n != -1)
  {
    // get the ID
    string val=dt2.Rows[n][dcParent].ToString();
    // search the child for all records where child.parentID=parent.ID
    string expr=dcParent.ColumnName+"="+val;
    // save the rows, as we'll use them later on when navigating the child
    ti.dataRows=dt.Select(expr);
  }
  // return the length
  return ti.dataRows.Length;
}

Moving Around

Each handler -- first, previous, next and last -- has basically the same form. I'll demonstrate the "next" handler. Each button in any given navigation bar is "tagged" with the DataTable on which it operates. From this information, the tableInfo object is accessed in order to update the internal record position. Note that for child records, this position is relative to the rows selected by the parent ID, as opposed to a position relative to all the records in the child table.

private void NextRecord(object sender, EventArgs e)
{
  Button btn=sender as Button;
  DataTable dt=btn.Tag as DataTable;
  TableInfo ti=tableInfo[dt] as TableInfo;
  if (ti.pos < ti.rows)
  {
    ((TableInfo)tableInfo[dt]).pos++;
    NextRecord(dt, ti);
    UpdateRecordCountInfo(dt);
  }
}

For this reason, a little bit of manipulation is necessary to acquire the desired record. If the table is a root table, then there is a 1:1 correlation between our internal position and the rows in the DataTable. However, if it is a child table, then we have to find the row in the DataTable that matches our row in the selected rows.

private void NextRecord(DataTable dt, TableInfo ti)
{
    if (dt.ParentRelations.Count==0)
    {
        BindingContext[dt].Position++;
    }
    else
    {
        // get the next row that matches the parent ID
        SetPositionToRow(dt, ti.dataRows[ti.pos-1]);

    }
    ResetAllChildren(dt);
}

This is done with rather brute force and could be optimized to look forward or backward from its current position. Oh, well. Next version...

private void SetPositionToRow(DataTable dt, DataRow row)
{
  for (int i=0; i < dt.Rows.Count; i++)
  {
  if (dt.Rows[i]==row)
    {
      BindingContext[dt].Position=i;
      break;
    }
  }
}

Updating Children

Now, when we change to another record in a parent table, all the children need to be updated to display the set of rows that relate to the parent record. This is accomplished recursively. The matching rows of all children is acquired and the child is set to the first record if it exists. Then the same is done for its children.

private void ResetAllChildren(DataTable dt)
{
  // update all children of the table to match our new ID
  foreach (DataRelation dr in dt.ChildRelations)
  {
    DataTable dtChild=dr.ChildTable;
    ResetChildRecords(dtChild);
  }
}

private void ResetChildRecords(DataTable dt)
{
  int n=GetMatchingRows(dt);
  TableInfo ti=tableInfo[dt] as TableInfo;
  ti.pos=1;
  ti.rows=n;
  UpdateRecordCountInfo(dt);
  if (n != 0)
  {
    SetPositionToRow(dt, ti.dataRows[0]);
  }
  foreach (DataRelation dr in dt.ChildRelations)
  {
    DataTable dtChild=dr.ChildTable;
    ResetChildRecords(dtChild);
  }
}

Adding a Record

Adding a record is rather nasty. Records are added to the end of the collection, which helps a bit. Any relational fields to the parent must be set to the parent ID and all child relationships must have a new record created, as well... Recursively, of course.

private void NewRecord(object sender, EventArgs e)
{
  Button btn=sender as Button;
  DataTable dt=btn.Tag as DataTable;
  dt.Rows.Add(dt.NewRow());
  int newRow=dt.Rows.Count-1;
  BindingContext[dt].Position=newRow;

  TableInfo ti=tableInfo[dt] as TableInfo;

  // Set the child relationship ID's to the parent!
  // There will be only one parent relationship except
  // for the root table.
  if (dt.ParentRelations.Count != 0)
  {
    DataRelation parentRelation=dt.ParentRelations[0];
    DataTable dt2=parentRelation.ParentTable;
    int n=BindingContext[dt2].Position;

    // this is always a 1:1 relationship
    DataColumn dcParent=parentRelation.ParentColumns[0];
    DataColumn dcChild=parentRelation.ChildColumns[0];
    string val=dt2.Rows[n][dcParent].ToString();
    dt.Rows[newRow][dcChild]=val;

    n=GetMatchingRows(dt);
    ti.pos=n;
    ti.rows=n;
  }
  else
  {
    ti.pos=newRow+1;
    ti.rows=newRow+1;
  }

  UpdateRecordCountInfo(dt);

  // for each child, also create a new row in the child's table
  foreach (DataRelation childRelation in dt.ChildRelations)
  {
    DataTable dtChild=childRelation.ChildTable;
    NewRecord(dt, dtChild, childRelation);
  }
}

...and for each child table...

private void NewRecord(DataTable parent, DataTable child, DataRelation dr)
{
  // add the child record
  child.Rows.Add(child.NewRow());

  // get the last row of the parent (this is the new row)
  // and the new row in the child (also the last row)
  int newParentRow=parent.Rows.Count-1;
  int newChildRow=child.Rows.Count-1;

  // go to this record
  BindingContext[child].Position=newChildRow;

  // get the parent and child columns
  // copy the parent ID (auto sequencing) to the child to establish
  // the relationship.  This is always a 1:1 relationship
  DataColumn dcParent=dr.ParentColumns[0];
  DataColumn dcChild=dr.ChildColumns[0];
  string val=parent.Rows[newParentRow][dcParent].ToString();
  child.Rows[newChildRow][dcChild]=val;

  ((TableInfo)tableInfo[child]).pos=1;
  ((TableInfo)tableInfo[child]).rows=1;
  UpdateRecordCountInfo(child);

  // recurse into children of this child
  foreach (DataRelation childRelation in child.ChildRelations)
  {
    DataTable dt2=childRelation.ChildTable;
    NewRecord(child, dt2, childRelation);
  }
}

Deleting a Record

Interestingly, deleting a record is very straightforward. This is thanks to cascading deletes, which the DataSet automatically enables.

private void DeleteRecord(object sender, EventArgs e)
{
  Button btn=sender as Button;
  DataTable dt=btn.Tag as DataTable;
  int n=BindingContext[dt].Position;
  dt.Rows.RemoveAt(n);
  ...

...followed by a bunch of code to display a valid record and reset the children.

Data Binding

Data binding makes life incredibly easy with regards to associating a control with a column in a DataTable, and is accomplished with one line:

ctrl.DataBindings.Add("Text", dt, dc.ColumnName);

This binds the "Text" field of the control to the specified data table and column. Isn't reflection great? The BindingContext is another life-saver. It allows us to specify the row in each DataTable that is used to bind the controls. Awesome! For example, given the table, we can specify the binding row with one line:

BindingContext[dt].Position=dt.Rows.Count;

XPath Queries

Screenshot - XPath.jpg

I implemented XPath capabilities so that I could play with how to extract information from the XML data. Coming from a database background, I wanted something that would flatten the hierarchy so that I could see all the data at once, without needing to mouse-click, etc. through layers of hierarchy. Using the SelectNodes method of the XmlDataDocument:

XmlNodeList nodeList=null;
try
{
  nodeList=doc.SelectNodes(edXPath.Text);
  DlgXPathResult dlg=new DlgXPathResult(nodeList);
  dlg.ShowDialog(this);
}

I extract a node list and, if it's successful, pass it on to a dialog box. The data is displayed in a ListView control with headers extracted from XmlNode. There are three basic steps in displaying node data:

  1. Get the headers.
  2. Fill the rows with data.
  3. Clean up empty columns.

Getting Header Information

The header information is extracted from both the attributes and the elements of the node list. This function operates recursively on elements and therefore can generate unwanted columns. Also, duplicate element names are ignored, which can lead to overwrite problems if your schema uses the same element name in two different areas and you happen to query on those elements.

private void ProcessChildHeaders(XmlNode node, XmlNode child)
{
  while (child != null)
  {
    // process attributes
    if (child.Attributes != null)
   {
      foreach(XmlAttribute attr in child.Attributes)
      {
        if (!cols.Contains(attr.Name))
        {
        cols.Add(attr.Name, colIdx);
        colHasData[colIdx]=false;
        lvResults.Columns.Add(attr.Name, -2, HorizontalAlignment.Left);
        ++colIdx;
        }
      }
    }
    // if this child is an element, get its children
    if (child.FirstChild is XmlElement)
    {
      ProcessChildHeaders(node, child.FirstChild);
    }
    else
    {
      // if not, then either it or its child is a text element
      string name=child.Name=="#text" ? node.Name : child.Name;
      if (!cols.Contains(name))
      {
        // add the column header
       cols.Add(name, colIdx);
       colHasData[colIdx]=false;
       lvResults.Columns.Add(name, -2, HorizontalAlignment.Left);
       ++colIdx;
      }
    }
    child=child.NextSibling;
  }
}

Fill the Rows with Data

This function inspects each child node for attribute values and text values, and recurses into child elements. Some logic is used to prevent empty rows.

private void ProcessChildData(XmlNode node, XmlNode child)
{
  while (child != null)
  {
    ProcessAttributes(child);

    // if this child is an element, get its children
    if (child.FirstChild is XmlElement)
    {
      ProcessChildData(child, child.FirstChild);
      if (hasAttributes | hasData)
      {
        lvi=CreateLVI(cols.Count);
        lvResults.Items.Add(lvi);
        hasData=false;
        hasAttributes=false;
      }
    }
    else
    {
      // if not, then either it or its child is a text element.
      string name=child.Name=="#text" ? node.Name : child.Name;
      int n=(int)cols[name];
      // set the data for the column
      lvi.SubItems[n].Text=child.InnerText;
      hasData=true;
      colHasData[n]=true;
    }
  child=child.NextSibling;
  }
}

Conclusion

After writing all this, I finally feel like I have a set of tools that I can use to generate schemas and manipulate the XML data. While not addressing all the issues of schemas, facets, etc. (the "choice" schema element looks particularly nasty), I feel that I've created a good set of tools for accomplishing 90% for which I need schemas and XML files. If there's any particular feature you feel is a "must have," let me know and I'll try to encorporate it.

History

Oct 15, 2003 - Added support for more complex schemas, fixed some minor bugs

License

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

About the Author

Marc Clifton
United States United States
Member
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.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralYou beautymemberMember 992525319 Mar '13 - 13:44 
This is perfect, thanks very much for sharing
QuestionMultiline TextBoxmemberMember 876304429 Mar '12 - 23:13 
That textbox should be multiline.
When I Put Question like for e.g.
What is the output of following JavaScript code?
<script type="text/javascript">
x=4+"4";
document.write(x);
</script>
 
Above text is not coming in multiline textbox.
When I entered the text in editor it showing in one line only like
What is the output of following JavaScript code?<script type="text/javascript">x=4+"4";document.write(x);</script>

Please Tell me how I can make the texteditor multiline?
QuestionHow to get similar functionality in web application?memberRajee1 Feb '12 - 21:47 
Hi Marc,
How do i get similar functionality in asp.net application? Do you have any web version of this functionality?
Thanks,
Rajee.
QuestionProblem reading my XSD schemamemberMember 83652361 Nov '11 - 2:40 
Hi there,
 
First of all the XML data editor you provide is perfect for my needs, but I have a problem with the XSD schema that I must read DataSet does not support union or list as simpleType.
 
Is there any chance you may be able to correct this bug? Here is the XSD schema
 
http://www.gsis.gr/psp/psp-2.3.xsd
 
Please let me know if you can help on this.
 
Thanks
Theo
AnswerRe: Problem reading my XSD schemaprotectorMarc Clifton1 Nov '11 - 3:26 
Hi Theo,
 
I'm rather swamped right now and really won't be able to look at this for a while.
 
Marc

QuestionData Binding Issuememberpchak6 Oct '11 - 5:05 
Hi Marc,
Great job on solving what could be a very complex problem. You app reads very complex schemas, and presents them nicely.
 
However, it seems that there is an issue with data binding. I populate a few elements, and upon save, get only an xml containing .
 
If I query the datatables, I find no rows anywhere that I have put data (before or after acceptchanges).
 
Any ideas?
 
Thanks,
Bill
Bill Polewchak
Sr. Technical Design Lead
SolutionArchitecture
Avery Dennison Corp.

QuestionData validationmemberasd2022714 Sep '11 - 20:44 
Hi and thanks for the great stuff.
 
I'm new around here and I would like to ask if data validation is possible with the editor?
 
(e.g. prompting the user about inputting a string that would have been an integer)
 
Many thanks!
 
asd20227
AnswerRe: Data validationprotectorMarc Clifton15 Sep '11 - 2:39 
asd20227 wrote:
I'm new around here and I would like to ask if data validation is possible with the editor?

 
It would have to be coded into the editor, but XSD supports something called "facets" which allows you to do some minimal validation.
 
Marc

GeneralRe: Data validationmemberasd2022715 Sep '11 - 23:17 
Thanks very much! Already been a great help starting from your source.
 
By the way (and off-topic), your blog was an enjoyable read and I was delighted to find a whole lot of heart in your texts. Congratulations from Hong Kong, China.
 
asd20227
QuestionXUME?memberGer Hayden27 Jun '11 - 0:25 
I may well have found my XUME - Xml Universal Message Editor.
 
I am off to study this now - then I'll wade in with a vote.
Ger

GeneralError reading a big schemamemberluotope26 Nov '09 - 5:40 
Hi,
I found this excellent tool by accident. Of course I tried it with a schema which I use with my work. That is called pain.001.001.02.xsd which is global ISO20022 standaRD schema.
 
The error happens in line: doc.DataSet.ReadXmlSchema(tr) and the error says:
 
System.ArgumentException was unhandled
Message="The table (Amt) cannot be the child table to itself in nested relations."
...
callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
 
If you are interested, I can send you the schema. More information about it here:
[]
 
Petri
GeneralRe: Error reading a big schemaprotectorMarc Clifton26 Nov '09 - 11:03 
luotope wrote:
"The table (Amt) cannot be the child table to itself in nested relations."

 
I believe this is a limitation of .NET parsing the schema.
 
Marc
 
Will work for food.
Interacx


I'm not overthinking the problem, I just felt like I needed a small, unimportant, uninteresting rant! - Martin Hart Turner


GeneralNeed Marc Clifton Contact Infomemberhussain2luv28 Apr '08 - 8:37 
Hi Do anyone have contact Information of Marc Clifton i already sent him mails to his marc.clifton@gmail.com but unfortunatly no replies so was just wondering is he using still this id? if not can anyone provide me latest contact info
 
thanks
Questionerror with GetLocalElement(....) function [modified]memberhussain2luv17 Apr '08 - 5:44 
GetLocalElement() method that seems to have addressed an apparent problem the code was having when dealing with complexTypes that were extensions of a base complexType.... For some reason the code wasn't seeing element members of the derived complexType that didn't originally belong to the base.
 
i seen many of them already described this problem in the post so please if u did any modifications to code can u please let me know iam still facing a prob in reading an XSD file ( i could able to read couple of XSD files but not others)Frown | :(
 

thanks

 
modified on Friday, April 18, 2008 9:27 AM

Generalhelp needed plzzzzzzzzzzzzmemberhussain2luv13 Apr '08 - 9:33 
hi iam still waiting for the updated version of dynamica xml editor plzzzzzzzzzzzzz can anyone send me to my email (shaik.hussain@gmail.com) iam in desperate need of it
 
thanks
firdos
GeneralNeed Help Plzzzzzzzzzzzzzzzzzzzmemberhussain2luv8 Apr '08 - 11:17 
Hi Marc,
I really appriciate for taking time to read to my message. well iam looking something like loading the form controls (whatever it is)along with treeview dynamically from the xsd schema

Well i guess you(or Randy) have updated the source code i really appriciate if you can send me the one to my email with is shaik.hussain@gmail.com
 
thanks
Firdos
 
modified on Tuesday, April 8, 2008 5:25 PM

GeneralRe: Need Help PlzzzzzzzzzzzzzzzzzzzprotectorMarc Clifton28 Apr '08 - 12:41 
hussain2luv wrote:
Well i guess you(or Randy) have updated the source code i really appriciate if you can send me the one to my email with is shaik.hussain@gmail.com

 
Sorry, but I don't actually have that code. You're pretty much on your own for figuring out what you need.
 
Marc
 

QuestionHelp needed plz!memberKumar!2 Sep '07 - 19:41 
Hai!
This is Kumar!
After finished my engg degree, now i am working in a s/w company!
And my first work there is to Generate EDI streams(837P) as per HIPAA low using XSD
(I had rule file sheet for 837P) and XML. first i need to insert my DB values into a xml file after validating with the values against rule file! After finishing this, based on that xml file that i have to generate an stream!
I fell that, your concept is something like that! can you please give me some ideas to do this! This is my first work, so i have to do more carefully!

GeneralDynamic XML editormemberJeffrey kwok21 Jul '07 - 2:16 
Hi Marc,
 
Do you have a sample that shows how to dynamically create a XML file based on a XSD schema and The idea is to have a treeview on the left and a property grid on the
right.
The treeview is loaded with the root elements from the schema.
When the user right click on a node, a context menu allow him to add
subnodes if schema allow it
GeneralRe: Dynamic XML editorprotectorMarc Clifton21 Jul '07 - 2:37 
Jeffrey kwok wrote:
Do you have a sample that shows how to dynamically create a XML file based on a XSD schema and The idea is to have a treeview on the left and a property grid on the
right.

 
I don't have that specific example, but look at:
 
XTree Part I[^]
XTree Part II[^]
XTree Part III[^]
 
It wouldn't take much to generate the XML tree template from the XSD or modify the popup to use the XSD for the node management. One thing you'd have to do is create a generic controller though, which should be straightfoward.
 
Marc
 


 

QuestionUpdated version?memberTrent_Ballew15 Mar '07 - 5:46 
I've seen mention of many changes you've made in the posts, so I'm sure many of us would love the most up-to-date version (hopefully, it's using VS 2005). Can you update the files in the article please?
 
Good article.
 
Trent Ballew

GeneralRe: Updated version?memberTomas Hjelmberg18 Dec '07 - 23:07 
That would be great!
QuestionIs there a limit on the size of the xsd or the number of elements?memberlearnerplates27 Feb '07 - 6:26 
I have an XSD that failed to load, the XSD is valid, I think the problem maybe with the Gui not being able to handle large amounts of elements. I removed half of them and it loaded fine.
Nice work.
 
http://learnerps-dotnet.blogspot.com

GeneralNamespace is not available to be referenced in this schema.memberThinsak30 Nov '06 - 8:57 
I tried to open my existing schema but I got this error message;
--------
Namespace "http://ebxml.customs.go.th/schema/ExportDeclaration_3_03" is not available to be referenced in this schema.
--------
The schema is created by a standards organisation so I don't think
there should be a problem there.
Anyone know how to resolve this?
Thank you in advanceBig Grin | :-D
Thinsak
 
Hello from Thailand!!

QuestionCould not be able to access UCTabStrip.xsd,UCTabStrip.xmlmemberseemasharma30 Apr '06 - 23:18 
i want to use this usercontrol for tabstrip in my project but as this xml and .xsd files are created by using some editor so i m unable to access these files.i have putted the path of file in web.config also it shows an error "could not find the path.".please solve my problem.i m using it in asp.net with vb.
 

 
-- modified at 5:21 Monday 1st May, 2006
Question"Annotations" for fields (elements)?memberA Kauchali28 Feb '06 - 21:18 
Is there any way for the XSD elements for fields to allow additional annotations for "friendly" field names?
 
So, orderDate could be displayed as "Date of Order" etc.
 
Where does such type of (meta?) data go in the XSD?
 
Kind regards
 
A Kauchali
QuestionMyXAML versionmemberOliver Canada21 Feb '06 - 2:28 
Congratulations for you tool. Simple and efficient.
Did you already write a MyXAML version? I would be interested in.
Thanks in advance for your answer.

 
Oliver
Generalmissing files in downloadmemberwebber12345623 Jan '06 - 7:12 
unfortunately the sample files referenced in the article are not included in the download ....
 
can you please update the download files ?
GeneralXSD File fails to prime appmemberodylisbeep15 Nov '04 - 13:06 
Great app, especially your XSD editor!
I tried reading in a simple xsd file generated in your XSD editor, but it would not load the datatables in the xml editor app.
I also tried reading in a XSD file I'm using for a research project, same problem.
I could not figure your SampleSchema.xsd because it was in some binary format.
Could you please explain limits of XSD file which would prime your app.
I could mail you the XSD file if you could supply a mail address.
I would also be willing to support the app financially since I think it is really good and am using code fragments in my research project.
QuestionSupport for repeating elements?sussRW788 Nov '04 - 0:13 
Hi,
 
Does this program support the minOccurs and maxOccurs attributes for repeating elements?
 
Thanks,
R
GeneralCode ModificationmemberRandy Grohs2 Aug '04 - 19:37 
Hi Marc,
 
This article and the accompanying code were a really great tutorial! Thank you. I made an alternate version of the program that, instead of creating GroupBoxes, uses a combination of a TreeView + TabControls + GroupBoxes to wrap elements. If you're interested, I would be glad to send the modified version to you.
 
Also, I wanted to let you know that I made a minor modification to the GetLocalElement() method that seems to have addressed an apparent problem the code was having when dealing with complexTypes that were extensions of a base complexType.... For some reason the code wasn't seeing element members of the derived complexType that didn't originally belong to the base.
 
I changed:
 
XmlSchemaSequence seq=ct.Particle as XmlSchemaSequence;
 
to:
 
XmlSchemaSequence seq=ct.ContentTypeParticle as XmlSchemaSequence;
 
The documentation for the "ContentTypeParticle" states that it:
 
Gets the particle which holds the post-compilation value of the ContentTypeParticle property. This ContentTypeParticle is determined after the content models of the most derived types and the base complex type have been resolved...
 
Apparently, this version of "particle" is a more current version
 
Thanks again,
Randy

GeneralRe: Code ModificationprotectorMarc Clifton13 Aug '04 - 3:47 
Hi Randy,
 
Sorry for the delay in getting back to you! I'd definitely be interested in taking a look at your modifications. Can you email the updates to:
 
webmaster@knowledgeautomation.com
 
I appreciate it!
 
Marc
 
Microsoft MVP, Visual C#
MyXaml
MyXaml Blog
Hunt The Wumpus
RealDevs.Net
GeneralRe: Code Modificationmembermukeshdas4 Mar '07 - 23:43 
Hi Randy,
 
If possible, could you please send me the modified source code. I need it desparately.
 
My e-Mail : das.mukesh@gmail.com
 
Thanks,
 
Mukesh
 

GeneralRe: Code Modificationmemberhussain2luv8 Apr '08 - 11:20 
Hi Randy,
I really appriciate if you can help me iam in desperate need of loading the controls along with treeview from the XSD schema and i read your blog and finds like it suits to my application. so plz plz can you send me the updated source code (updated one from Marc Clifton)
 
once again thanks
Firdos
GeneralProgramm start failsmemberrsoese17 Jun '04 - 12:20 
I just recently downloaded this tool. After unzipping and starting the exe i got this error. What went wrong and are there any other versions of this tool?
 
"Appl. could not be initialised (0xc0000135)...."
 
Help is very welcomeWink | ;-)
GeneralRe: Programm start failsprotectorMarc Clifton17 Jun '04 - 13:10 
rsoese wrote:
"Appl. could not be initialised (0xc0000135)...."
 
Never saw that before. Do you have .NET 1.1 installed?
 
Marc
 
Microsoft MVP, Visual C#
MyXaml
MyXaml Blog
Generalsame table cannot be the child table ...memberaakhter7 Jun '04 - 17:52 
The XML Data Editor looks great. Unfortunately, the first XSD I tried to load in there died with this output:
 
System.ArgumentException: The same table (passwords) cannot be the child table in two nested relations.
at System.Data.DataRelation.CheckNestedRelations()
at System.Data.DataRelation.set_Nested(Boolean value)
at System.Data.XSDSchema.InstantiateTable(XmlSchemaElement node, XmlSchemaComplexType typeNode, Boolean isRef)
at System.Data.XSDSchema.HandleTable(XmlSchemaElement node)
at System.Data.XSDSchema.LoadSchema(XmlSchema schemaRoot, DataSet ds)
at System.Data.DataSet.ReadXSDSchema(XmlReader reader, Boolean denyResolving)
at System.Data.DataSet.ReadXmlSchema(XmlReader reader, Boolean denyResolving)
at System.Data.DataSet.ReadXmlSchema(TextReader reader)
at xmlDataEditor.Form1.mnuOpenXSD_Click(Object sender, EventArgs e)
at System.Windows.Forms.MenuItem.OnClick(EventArgs e)
at System.Windows.Forms.MenuItemData.Execute()
at System.Windows.Forms.Command.Invoke()
at System.Windows.Forms.Control.WmCommand(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
 

************** Loaded Assemblies **************
mscorlib
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/microsoft.net/framework/v1.1.4322/mscorlib.dll
----------------------------------------
xmlDataEditor
Assembly Version: 1.0.1227.28253
Win32 Version: 1.0.1227.28253
CodeBase: file:///C:/Documents%20and%20Settings/Aamer%20Akhter/Desktop/XmlDataEditor_src/bin/Debug/xmlDataEditor.exe
----------------------------------------
System.Windows.Forms
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/system.windows.forms/1.0.5000.0__b77a5c561934e089/system.windows.forms.dll
----------------------------------------
System
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/system/1.0.5000.0__b77a5c561934e089/system.dll
----------------------------------------
System.Xml
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/system.xml/1.0.5000.0__b77a5c561934e089/system.xml.dll
----------------------------------------
System.Data
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/system.data/1.0.5000.0__b77a5c561934e089/system.data.dll
----------------------------------------
System.Drawing
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/system.drawing/1.0.5000.0__b03f5f7f11d50a3a/system.drawing.dll
----------------------------------------
 
====
xsd:
 


<!-- edited with XMLSPY v2004 rel. 4 U (http://www.xmlspy.com) by bob (bobo) -->
<!--W3C Schema generated by XMLSPY v2004 rel. 4 U (http://www.xmlspy.com)-->



could be ipv4 address, ipv6 address, attribute type determines




















































































lower priority gets tried first, negative values mean disable



 
Any help would be greatfully apprecidated
GeneralRe: same table cannot be the child table ...memberRandy Grohs2 Aug '04 - 20:33 
Howdy...
 
I found the same issue with one of my schemas and I made a {lame} workaround that could potentially require lots of refactoring of the schema....   Note - I'm not trying to provide a solution here, but here's a bit more info in case someone else actually figures out a real fix....
 
Here's a simple schema that illustrates the issue:
 
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
     <xs:complexType name="myComplexType">
          <xs:sequence>
               <xs:element name="complexElement1" type="subElement1Type"/>
               <xs:element name="simpleElement1">
                    <xs:simpleType>
                         <xs:restriction base="xs:string">
                              <xs:enumeration value="choice1"/>
                              <xs:enumeration value="choice2"/>
                              <xs:enumeration value="choice3"/>
                         </xs:restriction>
                    </xs:simpleType>
               </xs:element>
               <xs:element name="simpleElement2" type="xs:date"/>
          </xs:sequence>
     </xs:complexType>
     <xs:complexType name="subElement1Type">
          <xs:sequence>
               <xs:element name="TestElement1" type="xs:date"/>
          </xs:sequence>
     </xs:complexType>
     <xs:element name="myRootElement" type="myComplexType"/>
     <xs:element name="myRootElement2" type="myComplexType"/>
</xs:schema>
 

Now, the following schema has been refactored, and it works with the tool:
 
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
     <xs:complexType name="myRoot1ComplexType">
          <xs:complexContent>
               <xs:extension base="myBaseComplexType">
                    <xs:sequence>
                         <xs:element name="root1ComplexElement" type="subElement1Type"/>
                    </xs:sequence>
               </xs:extension>
          </xs:complexContent>
     </xs:complexType>
     <xs:complexType name="myRoot2ComplexType">
          <xs:complexContent>
               <xs:extension base="myBaseComplexType">
                    <xs:sequence>
                         <xs:element name="root2ComplexElement" type="subElement1Type"/>
                    </xs:sequence>
               </xs:extension>
          </xs:complexContent>
     </xs:complexType>
     <xs:complexType name="myBaseComplexType">
          <xs:sequence>
               <xs:element name="simpleElement1">
                    <xs:simpleType>
                         <xs:restriction base="xs:string">
                              <xs:enumeration value="choice1"/>
                              <xs:enumeration value="choice2"/>
                              <xs:enumeration value="choice3"/>
                         </xs:restriction>
                    </xs:simpleType>
               </xs:element>
               <xs:element name="simpleElement2" type="xs:date"/>
          </xs:sequence>
     </xs:complexType>
     <xs:complexType name="subElement1Type">
          <xs:sequence>
               <xs:element name="TestElement1" type="xs:date"/>
          </xs:sequence>
     </xs:complexType>
     <xs:element name="myRootElement" type="myRoot1ComplexType"/>
     <xs:element name="myRootElement2" type="myRoot2ComplexType"/>
</xs:schema>
 

As you can see, the workaround is a pain in the glutes because you have to extract all complex elements from reused global complexTypes, and put them into derived complexTypes giving them unique names.   This also means that code that references these types, has to know which version it is... It seems as if the only elements that can exist in a reused global complexType are simpleType elements....  
 
Anyway, if anyone has a better workaround (or better yet, a real FIX) let us know.   For deep, hierarchical schemas that reuse lots of types, my current workaround could be too much rework...
 
My perception from reading the MS docs is that this is issue is directly related to the use of DataSets... it appears as if the previous DataSet implementation didn't even use XML/XSD (it supported a different intermediate format of some kind).   It may be that even though we can now {thankfully} describe a DataSet using XSD, that it wasn't really designed to map extremely complex arbitrary schemas into....   Perhaps you have to be aware of the DataSet limitations when you design the schema....
 
Anyone have a silver bullet for us?   I like using the DataSet, but it appears to have a "universal XSD mapping" limitation...
 
-Randy

GeneralRe: same table cannot be the child table ...memberMatt Frame3 Nov '04 - 6:44 
Randy,
 
It looks like VS.Net 2005 Beta 1 has addressed this issue. I am however very interested in your treeview version and as wondering if you would care to share with others. If so you can contact me at mdframeATsorvive.com.
 
Thanks,
 
Matt
QuestionGrid view?memberrjacobson28 Dec '03 - 11:48 
This is a great utility... I've been trying to kludge together my own basic XML editor (after being frustrated with utilities like XMLSpy and InfoPath for simple tasks) but yours fits the bill very nicely.
 
One feature request: would there be a way to display repeating elements using datagrids, rather than displaying one at a time? (For example, a parent datagrid to display each order, and a child datagrid to display each item ordered.) This would make it easier to visualize and edit repeating elements. The basic technique for using master/detail datagrids is discussed here:
 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/vbtskcreatingmasterdetailslistwithdatagrid.asp
 
Also, there seems to be a bug: in your program with the example schema, the user is allowed to enter multiple billing addresses and multiple shipping addresses. However, the schema defines each of these as a single element, so multiple shipping or billing addresses would apparently violate the schema. It might make more sense to remove the record navigation bar for single elements.
AnswerRe: Grid view?editorMarc Clifton29 Dec '03 - 0:47 
Thanks for your comments!
 
rjacobson wrote:
would there be a way to display repeating elements using datagrids,
 
Perhaps, but I have no plans to do so. The DataGrid is a very cumbersome object with what I think is a poorly implemented UI. It also doesn't natively support comboboxes, though I found some third party code to handle this problem.
 
rjacobson wrote:
Also, there seems to be a bug
 
This is not really a bug. The elements are contained in a complex type, and there are no requirements that there be only one instance of the containing type, so the nav bars are correct.
 
The only way to correct this, and something I'd like to get around to doing one day, is to use the MinOccurs and MaxOccurs facets as restrictions on the complex type. I think that's possible.
 
Marc

 
Latest AAL Article
My blog
Join my forum!
GeneralMissing XML filesussAlan Josephson22 Oct '03 - 2:38 
The sample XML file you mention (the one referenced by the .xsd) is not in the distribution.
GeneralRe: Missing XML filememberdgroves29 Oct '03 - 11:06 
There is also the matter of the name for the XSD file: the article calls for "sampleSchema2.XSD," but the only file on the distribution is "sampleSchema.XSD." There may be no difference, but it's confusing.
 
The article and code is excellent (with these small exceptions). I appreciate your willingness to share such well-developed code with the world.
Generalserialize from an classmemberSpass200315 Oct '03 - 4:10 
Hi Marc,
 
first of all - great job for this two editors - i like them!
but i have a litte problem
i have serialized a class to an xmldatadocument and get this xsd file:
 
























 

so but nothing happend if i load this in the editor, in a datagrid it works for me.
 
hope you have a litte time to give me an feedback
 
thx Mike
GeneralRe: serialize from an classeditorMarc Clifton15 Oct '03 - 4:21 
Hi Mike,
 
Send me the XSD file directly. In your message post, you have to click on "ignore HTML" for the text to show up. I'll take a look at it. I've made a lot of changes to handle more complicated schemas, so I'll check it out.
 
Marc
 
Latest AAL Article
My blog
Join my forum!
GeneralRe: serialize from an classmemberSpass200315 Oct '03 - 4:47 
<?xml version="1.0" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:element name="NewDataSet">
          <xs:complexType>
               <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element name="ReturnMessage">
                         <xs:complexType>
                              <xs:sequence>
                                   <xs:element name="IFX_ECD" type="xs:int" />
                                   <xs:element name="IFX_ETX" type="xs:string" />
                                   <xs:element name="SUBDOC">
                                        <xs:complexType>
                                             <xs:sequence>
                                                  <xs:element name="Data" type="xs:int" />
                                             </xs:sequence>
                                        </xs:complexType>
                                   </xs:element>
                              </xs:sequence>
                         </xs:complexType>
                    </xs:element>
               </xs:choice>
          </xs:complexType>
     </xs:element>
</xs:schema>
 

thx for the fast response. you have a update for your editors? Have you a link for it?
 
thx Mike
GeneralRe: serialize from an classmemberDotNetGeek15 Oct '03 - 16:46 
[SharpObjects#1]
namespace ObjectSchema
{
    NewDataSet (minOccurs="0" maxOccurs="unbounded")
    {
        ReturnMessage
        {
            int    IFX_ECD;
            string IFX_ETX;
            SUBDOC
            {
                int Data;
            }
        }
    }
}
 
Someday the world will understand that XML SUX !
GeneralRe: serialize from an classmemberDotNetGeek15 Oct '03 - 16:54 
[SharpObjects#2]
namespace ObjectSchema:
    NewDataSet (minOccurs="0" maxOccurs="unbounded"):
        ReturnMessage:
            int    IFX_ECD
            string IFX_ETX
            SUBDOC:
                int Data
            End
        End
    End
End
 
Someday the world will understand that XML SUX !
GeneralRe: serialize from an classmemberSpass200315 Oct '03 - 20:47 
ok this one is working - thx for your help Marc
 
<?xml version="1.0" standalone="yes"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
   <xs:element name="ReturnMessage">
      <xs:complexType>
         <xs:sequence>
            <xs:element name="IFX_ECD" type="xs:string" minOccurs="0" />
            <xs:element name="IFX_ETX" type="xs:string" minOccurs="0" />
            <xs:element name="SUBDOC" minOccurs="0" maxOccurs="unbounded">
               <xs:complexType>
                  <xs:sequence>
                     <xs:element name="Data" type="xs:string" minOccurs="0" />
                  </xs:sequence>
               </xs:complexType>
            </xs:element>
         </xs:sequence>
      </xs:complexType>
   </xs:element>
   <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:Locale="de-AT" msdata:EnforceConstraints="False">
      <xs:complexType>
         <xs:choice maxOccurs="unbounded">
            <xs:element ref="ReturnMessage" />
         </xs:choice>
      </xs:complexType>
   </xs:element>
</xs:schema>
GeneralXml Editor in asp.netmemberAC2624 Jul '03 - 13:07 
Hi,
I am coding an xml editor in asp.net. I am creating controls dynamically depending on the nodes in the xml file. I would like to implement the kind of navigation for entries/records that you have, with the ability to show the entries, in the same set of textboxes etc. How do I achieve that? Any help will be appreciated.
Thanks

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 15 Oct 2003
Article Copyright 2003 by Marc Clifton
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid