5

I have been reading over old threads here as well as pages I found on Google, and I can honestly say this has confused me completely. It seems there is about 1000 ways to parse XML strings using C# .NET and I don't know which to use. It seems all examples I find rely on a specific named root node and so on.

What I have is...

<whmcsapi version="4.1.2"> 
 <action>getstaffonline</action> 
 <result>success</result> 
 <totalresults>1</totalresults> 
 <staffonline> 
  <staff> 
   <adminusername>Admin</adminusername> 
   <logintime>2010-03-03 18:29:12</logintime> 
   <ipaddress>127.0.0.1</ipaddress> 
   <lastvisit>2010-03-03 18:30:43</lastvisit> 
  </staff> 
 </staffonline> 
</whmcsapi>

I only need to get the values for and each staff member's information (enclosed in tags). Can anyone tell me what the best way to do this would be and possibly a small example?

Thanks!

4 Answers4

12
var staff = XDocument.Parse(myXml)
    .Descendants("staff")
    .Select(n => new { 
                         adminusername = n.Element("adminusername").Value,
                         ...
                     });
Yuriy Faktorovich
  • 67,283
  • 14
  • 105
  • 142
3

Most commonly used is Linq to XML these days, it integrates XML parsing into Linq for a nice, succinct and expressive syntax:

XDocument xmlDoc = XDocument.Load(@"testData.xml");
var    staffMembers = xmlDoc.Descendants("staff")
                        .Select( staff => new { Name = staff.Element("adminusername").Value,
                                                LoginTime = staff.Element("logintime").Value,
                                                IpAddress = staff.Element("ipaddress").Value,
                                                LastVisit = staff.Element("lastvisit").Value,
                                            }).ToList();
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • I don't understand why this is having issues. No matter how I try it I get "illegal characters in path". Can I not load it like this from a string? http://www.ampaste.net/m3651f133 –  Jan 14 '11 at 18:37
  • 1
    to load from a string use `XDocument.Parse(myString)` – BrokenGlass Jan 14 '11 at 18:57
  • Ah thank you, I just noticed that from the other comment. Do you see why this wouldn't work? The two parts at the bottom of the method don't update the listbox and label, although the XML is being pulled correctly. So I assume it is a parsing problem. http://www.ampaste.net/m61f246e1 –  Jan 14 '11 at 19:06
  • Sorry, I think there site went down, the link should be working now. –  Jan 15 '11 at 03:56
0
XDocument doc = XDocument.Load("staff.xml");

var query = from r in doc.Descendants("staff")
            select new
                   {
                      Adminusername = r.Element("adminusername").Value,
                      LoginTime = r.Element("logintime").Value,
                      IpAddress = r.Element("ipaddress").Value,
                      LastVisit = r.Element("lastvisit").Value
                   };
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Scott Adams
  • 410
  • 3
  • 11
-3

Here is a function that I use that works perfectly to parse xml files. I have included a 'Delimeter' class that you can use to store xml delimeters like

<startTag></endTag>

Really easy to use, and works like a charm... let me know if you have any questions

Use the function like this:

XmlDataManager.List<XmlManager.Delimeter> delimeters = new List<XmlManager.Delimeter>("<result>","</result>"); 
int[] splitIndexArray = { 1 }; // Tells the function where to split in case where the same value occurs multiple times in a line... usually 1 need an entry for each value 
String testValue = "";
List<String> values = new List<String> {testValue}
XmlDataManager.ReadValues(delimeters, values, `<xmlFileNameHere>,` splitIndexArray);

Here is the class:

   public class XmlDataManager 
{
    const String XML_FILE_WRITE_FAIL = "Could not write to xml file";
    const String XML_FILE_READ_FAIL = "Could not read from xml file";
    const String XML_FILE_WRITE_BUILDER_FAIL = "Could not write values to string";  


   /// <summary>
    /// 
    /// </summary>
    public struct Delimeter
    {
        internal String StartDelimeter { get { return _startDelimeter; } }
        internal String EndDelimeter { get { return _endDelimeter; } }
        private readonly String _startDelimeter;
        private readonly String _endDelimeter;

        public Delimeter(String startDelimeter, String endDelimeter)
        {
            _startDelimeter = startDelimeter;
            _endDelimeter = endDelimeter;
        }

        public Delimeter(String startDelimeter)
        {
            _startDelimeter = startDelimeter;
            _endDelimeter = String.Empty;
        }
    }


    public static void ReadValuesLineByLine(    List<Delimeter> elementDelimeters, 
                                                List<String> values, 
                                                String fileName, 
                                                int[] splitIndexes)
    {
        try
        {
            using (StreamReader sr = new StreamReader(fileName))
            {
                String line = sr.ReadLine();
                while (!sr.EndOfStream)
                {
                    for (int i = 0; i <= values.Count-1; i++)
                    {
                        if (line.Contains(elementDelimeters[i].StartDelimeter))
                        {
                            String[] delimeters = { elementDelimeters[i].StartDelimeter, elementDelimeters[i].EndDelimeter };
                            String[] elements = line.Split(delimeters, StringSplitOptions.None);
                            values[i] = elements[splitIndexes[i]];
                        }
                    }
                     line = sr.ReadLine();
                }
            }
        }
        catch(Exception ex)
        {
            throw new Exception(XML_FILE_READ_FAIL, ex);
        }
    }
}

Peter

Zunandi
  • 164
  • 11
  • 1
    is there a reason why you invented your own XML parsing class when there is perfectly fine out of the box functionality to do just that? I'm a little shocked I have to say. – BrokenGlass Jan 15 '11 at 01:33
  • Seriously, why would you do that to yourself? – Jordan Nov 20 '12 at 16:36