0

I am trying to load an XML formatted string into my GUI using a TreeView control. However, the XML formated string is in proprietary layout.

The XML formatted string structure will look like this:

<Response>
    <Data>
     <Settings>
        <Setting>
            <SettingsXml>
               <ScanJobs>
                  <ScanJobsData>
                    <Mailboxes>
                      <Name>[email protected]|DB1</Name>
                      <Value>true</Name>
                    </Mailboxes>
                    <Mailboxes>
                      <Name>[email protected]|DB1</Name>
                      <Value>true</Name>
                    </Mailboxes>
                    <Mailboxes>
                      <Name>[email protected]|DB2</Name>
                      <Value>true</Name>
                    </Mailboxes>
                    <Mailboxes>
                      <Name>[email protected]|DB2</Name>
                      <Value>true</Name>
                    </Mailboxes>
                    <Mailboxes>
                      <Name>[email protected]|DB3</Name>
                      <Value>true</Name>
                    </Mailboxes>
                    <Mailboxes>
                      <Name>[email protected]|DB3</Name>
                      <Value>true</Name>
                    </Mailboxes>
                  </ScanJobsData>
               </ScanJobs>
            </SettingsXml>
        </Setting>
      </Setting>
    </Settings>
  </Data>
</Response>

Where inside tags we have a and tags. tag represents the name of the mailbox appended with Database name to which that mail box belongs. For example- [email protected] is the name of the mailbox which is associated with Database having name as DB1. Now I am getting the above xml formatted data in a String not as a XML file.

I'd like the output to be structured in TreeView as follows :

+DB1

+DB2

+DB3

I've been searching the web for the past few hours, and none of the results have helped. Some have come close, but perhaps properties won't show up, or node's names won't display, etc.

I'm writing in c# in Visual Studio 2010. Thanks for the help!

1
  • 1
    Your <Value> tags are ended with </Name> tags and there's a </Setting> too much on line 36 Commented Jan 11, 2013 at 6:57

2 Answers 2

1

Try this:

TreeView treeview = new TreeView();

// Get all the <Name> elements
XDocument doc = XDocument.Parse(xmlAsString);
var mailboxNames = doc.Element("Response").Element("Data").Element("Settings").Element("SettingsXml").Element("ScanJobs").Element("ScanJobsData").Elements("Mailboxes").Select(m => m.Element("Name"));

// Extract the email and db in each <Name> element
foreach (var name in mailboxNames)
{
    var namesSplit = name.Value.Split('|');
    var email = namesSplit[0];
    var db = namesSplit[1];

    // Create new db node if it not exists and add the email there
    if (!treeview.Nodes.ContainsKey(db))
    {
        TreeNode[] emails = new TreeNode[] { new TreeNode(email) };
        TreeNode node = new TreeNode(db, emails);
        treeview.Nodes.Add(node);
    }
    // If db node already exists, add email to currently existing node
    else
    {
        treeview.Nodes[db].Nodes.Add(email);
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

You may want to avoid splitting the same thing multiple times by assigning name.Value.Split('|') to a variable
You may use 'var doc = XDocument.Parse(xmlAsString);' instead loading xml from file, if your xml comes elsewhere, as you stated.
1

This query will return you sequence of DB TreeNodes with mail nodes already added to them:

XDocument xdoc = XDocument.Load(path_to_xml);
// or XDocument.Parse(xml_string);
var nodes = from m in xdoc.Descendants("Mailboxes")
            let name = m.Element("Name").Value.Split('|')
            select new {
                Mail = name[0],
                Db = name[1]
            } into md
            group md by md.Db into g
            select new TreeNode(g.Key, 
                                g.Select(x => new TreeNode(x.Mail)).ToArray());

Then simply

 treeView.Nodes.AddRange(nodes.ToArray());

3 Comments

I know man, I'm just not at the point where I can crap out queries like that in the blink of an eye :D
Actually it is possible to avoid anonymous type creation - we can group by name[1] and then select mail nodes from name[0], but that would be too match for blink of eye :)
nods with sheep-like look on face

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.