0

I'm attempting to create a program that reads the XML files that are generated in a very specific format :-

<?xml version="1.0" encoding="utf-8"?>
<RDCMan programVersion="2.7" schemaVersion="3">
  <file>
    <properties>
      <name>Example File</name>
    </properties>
    <group>
      <properties>
        <name>Guests</name>
      </properties>
      <group>
        <properties>
          <name>Test Service</name>
        </properties>
        <group>
          <properties>
            <name>Location 1</name>
          </properties>
          <server>
            <properties>
              <displayName>Server1</displayName>
              <name>server1.domain.com</name>
            </properties>
          </server>
        </group>
        <group>
          <properties>
            <name>Location 2</name>
          </properties>
          <server>
            <properties>
              <displayName>Server2</displayName>
              <name>server2.domain.com</name>
            </properties>
          </server>
        </group>
      </group>
    </group>
    <group>
      <properties>
        <name>Hosts</name>
      </properties>
      <group>
        <properties>
          <name>Location1</name>
        </properties>
        <server>
          <properties>
            <displayName>Host1</displayName>
            <name>host1.domain.com</name>
          </properties>
        </server>
      </group>
      <group>
        <properties>
          <name>Location2</name>
        </properties>
        <server>
          <properties>
            <displayName>Host2</displayName>
            <name>host2.domain.com</name>
          </properties>
        </server>
      </group>
    </group>
  </file>
</RDCMan>

This would produce a TreeView like the following mockup ;-

TreeView Mockup

Can anyone point me in the right direction? I've managed to create TreeViews from other XML formats successfully, but this one eludes me for some reason!

(p.s the observant among you may notice a striking similarity between the XML and a Remote Desktop Connection Manager file!)

Cheers in advance

Andy

  • See following posting : https://stackoverflow.com/questions/28976601/recursion-parsing-xml-file-with-attributes-into-treeview-c-sharp – jdweng Jul 25 '19 at 22:02
  • The XML in that post is very similar to the format I was originally using (successfully). Unfortunately, that was too constraining for our needs which is one reason why I need to use the Remote Desktop Connection Manager XML format I alluded to above. Also, using this format allows me to easily re-use our RDC Manager files (which contain several thousand servers!) instead of re-inventing the wheel and having to maintain two separate, extremely large, system lists. – Duckfather Jul 29 '19 at 10:47

1 Answers1

-1

Xml is Xml. What you really want is to get the same results in c# that you were getting on a different machine. The question is why you are getting a different number of server on the local machine as the remote machine. Are the two machines on the same subnet? Are the two machines running the same operating system (windows/linux)? What you are asking is to run an application on a remote machine and then process results locally. This may be more complicated than to solve the issue why local and remote machines are seeing different number of servers. Seeing different number of servers usually means they are on different subnets. It is possible that you are listening to the wrong ethernet connection on the local machine. To see all the ethernet data you need to make sure you are listening on IP.Any which receives all the subnets.

Try following code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication122
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            XElement file = doc.Descendants("file").FirstOrDefault();

            var result = file.Elements("group").Select(x => new
            {
                user = (string)x.Element("properties").Element("name"),
                server = x.Elements("group").Select(y => new {
                    serviceName = (string)y.Element("properties").Element("name"),
                    locations = y.Elements("group").Select(z => new {
                        locationName = (string)z.Element("properties").Element("name"),
                        servers = z.Elements("server").Select(a => new {
                            displayName = (string)a.Descendants("displayName").FirstOrDefault(),
                            serverName = (string)a.Descendants("name").FirstOrDefault()
                        }).ToList()
                    }).ToList()
                }).ToList()
            }).ToList();

         }
    }


}

Here is code loading a Treeview

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

namespace WindowsFormsApplication48
{
    public partial class Form1 : Form
    {
        const string FILENAME = @"c:\temp\test.xml";
        public Form1()
        {
            InitializeComponent();

            XDocument doc = XDocument.Load(FILENAME);
            XElement file = doc.Descendants("file").FirstOrDefault();

            foreach (XElement xUser in file.Elements("group"))
            {
                string user = (string)xUser.Element("properties").Element("name");
                TreeNode userNode = new TreeNode(user);
                treeView1.Nodes.Add(userNode);

                foreach (XElement xService in xUser.Elements("group"))
                {
                    string serviceName = (string)xService.Element("properties").Element("name");
                    TreeNode serviceNode = new TreeNode(serviceName);
                    userNode.Nodes.Add(serviceNode);
                    foreach (XElement xLocation in xService.Elements("group"))
                    {
                        string locationName = (string)xService.Element("properties").Element("name");
                        TreeNode locationNode = new TreeNode(locationName);
                        serviceNode.Nodes.Add(locationNode);
                        foreach (XElement xServer in xLocation.Elements("server"))
                        {
                            string displayName = (string)xServer.Descendants("displayName").FirstOrDefault();
                            string serverName = (string)xServer.Descendants("name").FirstOrDefault();
                            TreeNode serverNode = new TreeNode(displayName + "," + serverName);
                            locationNode.Nodes.Add(serverNode);

                        }
                    }
                }
            }
            treeView1.ExpandAll();
        }
    }
}

Here is recursive code to build the treeview

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

namespace WindowsFormsApplication48
{
    public partial class Form1 : Form
    {
        const string FILENAME = @"c:\temp\test.xml";
        public Form1()
        {
            InitializeComponent();

            XDocument doc = XDocument.Load(FILENAME);
            XElement file = doc.Descendants("file").FirstOrDefault();

            string name = (string)file.Element("properties").Element("name");
            TreeNode fileNode = new TreeNode(name);
            treeView1.Nodes.Add(fileNode);
            GetTree(file, fileNode);

            treeView1.ExpandAll();
        }
        void GetTree(XElement xParent, TreeNode parentNode)
        {
            foreach (XElement group in xParent.Elements("group"))
            {
                string groupName = (string)group.Element("properties").Element("name");
                TreeNode groupNode = new TreeNode(groupName);
                parentNode.Nodes.Add(groupNode);
                GetTree(group, groupNode);
            }
            foreach (XElement xServer in xParent.Elements("server"))
            {
                string displayName = (string)xServer.Descendants("displayName").FirstOrDefault();
                string serverName = (string)xServer.Descendants("name").FirstOrDefault();
                TreeNode serverNode = new TreeNode(displayName + "," + serverName);
                parentNode.Nodes.Add(serverNode);

            }


        }
    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • I'm sorry, but I think you misunderstand me. I'm not connecting to anything. I'm simply attempting to get a routine (in VB.NET or C#) that reads the above XML and builds a TreeView as shown in the attached mockup. – Duckfather Jul 29 '19 at 13:24
  • I updated answer with some code. The code is tricky due to recursive tag names. You can create a tree view from my results. – jdweng Jul 29 '19 at 14:35
  • Ahh, process the XML to get its elements **_before_** processing for the TreeView! Nice one! Thanks for info. This is working great now and got me out of a hole :) – Duckfather Jul 30 '19 at 09:38
  • The last recursive solution is very nice. – jdweng Jul 30 '19 at 12:41