tags:

views:

837

answers:

5

Following is the example of an XML document

<People>
   <Person>
       <Name>ABC </Name>
       <SSN>111111</SSN>
       <Address>asdfg</Address>
   </Person>
</People>

I need to get the Tag names but not the values between the tag names. i.e., Under Person Tag, I should grab the Name, SSN, Address nodes and not the ABC, 111111, asdfg values.

I need to use Linq to XML and query it in c#.

Any clue how to do it?

+4  A: 

This returns the names as a list of strings:

var doc = XDocument.Parse(@"<People>
   <Person>
       <Name>ABC </Name>
       <SSN>111111</SSN>
       <Address>asdfg</Address>
   </Person>
</People>"
);

var list = doc.Root.Element("Person").Descendants()
              .Select(node => node.Name.LocalName).ToList();

In case you're using an XElement instead of an XDocument, you can remove the .Root from the above code and get the correct results.

Ahmad Mageed
+1 for being the only answer so far to actually use LINQ with the LINQ to XML classes.
Joel Mueller
A: 

You can get it this way...

string xml = "<People> <Person> <Name>ABC </Name> <SSN>111111</SSN> <Address>asdfg</Address> </Person> <Person> <Name>ABC </Name> <SSN>111111</SSN> <Address>asdfg</Address> </Person> </People>";

XElement xmlData = XElement.Parse(xml);

foreach(XElement xmlPerson in xmlData.Elements("Person"))
{
    List<string> TagsForThisPerson = new List<string>();
    foreach(XElement xmlTag in xmlPerson.Elements())
    {
     TagsForThisPerson.Add(xmlTag.Name.ToString());
    }
    TagsForThisPerson.Dump();
}
Michael La Voie
+1  A: 

Create a class

public class Person
{
     public string Name {get; set;}
     public int SSN {get; set;}
     public string Address {get; set;}
}

And create a new person this way;

List<Person> NewPersons = new List<Person>();
XDocument doc = XDocument.Load(xmlFile);     
foreach(XElement xElem in doc.Descendants("Person"))
{
    NewPersons.Add(new Person
            {
                Name = xElem. Element("Name").Value,
                SSN = xElem.Element("SSN").Value,
                Address = xElem.Element("Address").Value,
            });
}
Baddie
A: 

I used this piece of code. But this would give me all the nodes into the _sourcefields list. But if i have to access particular node like for example for the above xml if I have to access only person's children without manually typing Name, SSN and address.. Please help me with this issue...

XDocument doc = XDocument.Load(FileName);

    // gets a list of the main elements
    var query = from c in doc.Root.Elements()
                select c;

    // somewhere to store the names
    List<string> elementNames = new List<string>();
    List<string> attributeNames = new List<string>();

    // loop for each of the main elements
    foreach (var q in query)
    {
        if (!elementNames.Contains(q.Name.ToString()))
            elementNames.Add(q.Name.ToString());

        // see if the element has any subelements
        if (q.HasElements)
        {
            var anotherQuery = from a in q.Elements()
                               select a;

            foreach (var a in anotherQuery)
            {
                if (!elementNames.Contains(a.Name.ToString()))
                    elementNames.Add(a.Name.ToString());
                //Console.WriteLine(elementNames);
                _sourceFields.Add(new SourceFieldInfo(a.Name.LocalName));
            }
        }

        // see if element has any attributes
        if (q.HasAttributes)
        {
            var anotherQuery = from a in q.Attributes()
                               select a;

            foreach (var a in anotherQuery)
            {
                if (!attributeNames.Contains(a.Name.ToString()))
                    attributeNames.Add(a.Name.ToString());
                //Console.WriteLine(attributeNames);
                _sourceFields.Add(new SourceFieldInfo(a.Name.LocalName));
            }
        }
    }
A: 

Simple Linq syntax to get the names... assumes you have the xml loaded in a XDocument variable named doc.

var nodeNames = from node in doc.Descendants("Person").First().Descendants()
                select node.Name.LocalName;

Update: Changed it to only look at the first person. If you have more than one in the xml document the list of names is probably not what you would want (no reason to repeat all the names of the nodes over and over). This way you get a list of just the node names for the first person, but it does assume that the first one would have a complete list of names. If they vary you would need to build a distinct list from all the nodes.

Brian ONeil