3

I'm working on an experimental TreeView where each TreeViewItem can either represent a condition, or a branch with an operator. This is to be parsed into SQL.

For example, the tree could have a branch with an "AND" or an "OR" operator, whose children would then be conditions. This is used to as to be able to generate the WHERE segment of an SQL statement, for example ((Name = 'Matt' AND AGE > 20) OR (Name = 'John' AND Age = 15)) AND Job = 'Student'.

How can I go about constructing that? What I've done so far is thought about placing a string,list<Condition> pair in a Tuple<>, where the string represents the branch operator (AND/OR), and the list represents the conditions contained within that branch.

However, since each branch can be split into a number of operator branches or conditions, it can get extremely complicated very quickly

Dot NET
  • 4,891
  • 13
  • 55
  • 98

2 Answers2

2

You can use recursive function to parse the treeview from top, so each root note of the treeview is one SQL statement:

e.g.:

enter image description here

function code:  

string getHead(TreeViewItem t)
            {
                string s = "";
                if (t.Items.Count == 0) //get the condition
                {
                    return s=t.Header.ToString(); //change this to your real getCondition function.
                }
                else
                {
                    for (int i = 0; i < t.Items.Count; i++ )
                    {
                        if(t.Items[i] is TreeViewItem) //Edit: only use treeviewitems not the button...
                        {
                          if (i == 0) // first note doesn't need the operator 
                          {
                            s += getHead(t.Items[0] as TreeViewItem);
                          }
                          else // only needs operator in between
                          {
                             s += (string.IsNullOrEmpty(getHead(t.Items[i] as TreeViewItem).Trim()) ? "" : (" " + t.Header + " " + getHead(t.Items[i] as TreeViewItem))); // only get real treeviewitem, not the one with two buttons and an empty header; change t.Header to your real getOperator function.

                          }
                        }                    
                    }
                    return string.Format("({0})",s); //group sub conditions
                }
            }

usage:

MessageBox.Show(getHead((treeView1.Items[0] as TreeViewItem)));

result:

enter image description here

Bolu
  • 8,696
  • 4
  • 38
  • 70
  • Thanks for the reply. Unfortunately, after each and every branch, I've got a TreeViewItem with a button. How can it skip that and still work recursively? – Dot NET Dec 17 '12 at 14:32
  • @DotNET, Updated, you need to add `if(t.Items[i] is TreeViewItem)` – Bolu Dec 17 '12 at 14:44
  • Hi again, I've almost got it working. For some reason, it keeps adding an "AND" or an "OR" at the end though. So I'm getting something like `(ID=5 AND Name=Matt AND)` – Dot NET Dec 17 '12 at 15:47
  • @DotNET, can you post your xaml for the `treeview`? I guess you have some empty `treeviewitem` (item without a header) – Bolu Dec 17 '12 at 15:53
  • I haven't got any XAML as the TreeView is generated at run-time by the user. If it helps, could I post a diagram explaining the structure? – Dot NET Dec 17 '12 at 15:54
  • @DotNET, updated, change the code in the `Else` to `s += (string.IsNullOrEmpty(getHead(t.Items[i] as TreeViewItem).Trim()) ? "" : (" " + t.Header + " " + getHead(t.Items[i] as TreeViewItem)));` – Bolu Dec 17 '12 at 16:05
  • I'll give it a try :) Sorry about taking long to reply, but the code requires a lot of modification since each TreeViewItem has a number of components inside. I'll let you know how it goes – Dot NET Dec 17 '12 at 16:13
  • Thanks! this is just the principle. – Bolu Dec 17 '12 at 16:24
0

In your tree view, aren't the last AND and OR supposed to be interchanged? I cannot get to the same parsed string you specified below with that view.

AND
    AND
         Job='Student'
         Age > 20
    AND
         OR
            Name='John'
            Name='Matt'
         Sex='Male'   

The last AND ands another OR condition and a single statement.

Not sure if this helps, but bison generates C code for bottom up parsing like this. You can give it a try.

e: conditional statement|
   e AND e|
   e OR e
;
Wander3r
  • 1,801
  • 17
  • 27