How to query nested XML Elements with Linq

mdeek
mdeek used Ask the Experts™
on
I have an XML File that follows similar structure (it is the API of of one of our vendors that returns this file) - it comes in looking like:

<folder name="something">
   <folder name="nice">
       <file name="cool" />
       <file name="jack" />
   </folder>
   <folder name="steve">
          <folders or files might go there>
   </folder>
</folder>

What id like to do is easily be able to get ALL of the files, and I can do that easily enough but I need to know the paths fo the files, like root/cool/filename or root/james/filename


<folder name="something">
   <folder name="nice">
       <file name="cool" />
       <file name="jack" />
   </folder>
   <folder name="steve">
          <folders or files might go there>
   </folder>
</folder>

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Craig WagnerSoftware Architect

Commented:
Do you have to use LINQ? I used the following file contents:

<folder name="something">
    <folder name="nice">
        <file name="cool" />
        <file name="jack" />
    </folder>
    <folder name="steve">
        <folder name="boo">
            <file name="hoo" />
        </folder>
    </folder>
</folder>

Along with the code snippet below to produce this output:

cool/nice/something/
jack/nice/something/
hoo/boo/steve/something/

Yes, the results are backwards, you'd have to build the string in the reverse order, but it gives you the general idea.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load( "XMLFile1.xml" );
 
XmlNodeList nodeList = xmlDoc.SelectNodes( "//file" );
 
foreach( XmlNode node in nodeList )
{
    XmlNode tempNode = node;
 
    do
    {
        if( tempNode.Attributes != null && tempNode.Attributes["name"] != null )
        {
            Console.Write( tempNode.Attributes["name"].Value + "/" );
        }
 
        tempNode = tempNode.ParentNode;
    } while( tempNode != null );
 
    Console.WriteLine();
}

Open in new window

Commented:
As you want linq way this will be your solution.
it get file name and its full path.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string textdata= @"<folder name='root'>
                                    <folder name='nice'>
                                        <file name='cool' />
                                        <file name='jack' />
                                    </folder>
                                    <folder name='steve'>                                
                                        <folder name='nice'>
                                            <file name='cool1' />
                                            <file name='jack2' />
                                        </folder>
                                    </folder>
                               </folder>";
            XDocument doc = XDocument.Parse(textdata);
            var data = from c in doc.Document.Descendants()
                       where c.Name == XName.Get("file")
                       select new { FileName = c.Attribute(XName.Get("name")).Value, Path = GetPath(c) };
            
        }
 
        private static string GetPath(XElement ele)
        {
            bool firsttime = true;
            StringBuilder bui = new StringBuilder();
            while (ele != null)
            {
                //returnVal += ele.Attribute(XName.Get("name")).Value + "/";
                if (firsttime)
                {
                    bui.Insert(0, ele.Attribute(XName.Get("name")).Value);
                    firsttime = false;
                }
                else
                {
                    bui.Insert(0, ele.Attribute(XName.Get("name")).Value + "/");
                }
                ele = ele.Parent;
            }
            return bui.ToString(); 
        }
    }
}

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial