Liam Hardy
Liam Hardy

Reputation: 155

XML to String List

I have some code that I need to put into a string list in C# and I am reading this code from an XML files and the layout of it is something like below...

<?xml version="1.0"?>
<accountlist>
    <main>
        <account id="1" special_id="4923959">
            <username>Adam</username>
            <motto>Hello Everyone>
            <money>1004</money>
            <friends>394</friends>
            <rareid>9</rareid>
            <mission>10</mission>
        </account>
    </main>
</accountlist>

How can I put each account tag into a string list? from the first < account > to the < / account > tag?

Please do NOT tell me to go to the link below as it does NOT work!! How to read a XML file and write into List<>?

So far I have tried the below code, and the string list just stays empty

XDocument doc = XDocument.Parse(this._accountsFile);

            List<string> list = doc.Root.Elements("account")
                               .Select(element => element.Value)
                               .ToList();

            this._accounts = list;

Upvotes: 4

Views: 1746

Answers (4)

Bakri Bitar
Bakri Bitar

Reputation: 1697

This will work on your example (but you need to close this tag <motto>Hello Everyone>

      public List<string> GetAccountsAsXmlList(string filePath)
      {
        XmlDocument x = new XmlDocument();

        x.Load(filePath);
        List<string> result = new List<string>();
        XmlNode currentNode;
        foreach (var accountNode in x.LastChild.FirstChild.ChildNodes)
        {
            currentNode = accountNode  as XmlNode;
            result.Add(currentNode.InnerXml);
        }
          return result;
      }

EDIT as an answer to your question:

Is there a way I can get the id and specal_id in a seperate string?

you can use currentNode.Attributes["YourAttributeName"].Value, to get the values.


assume you have class Account :

class Account
    {
        public string  accountXml { get; set; }
        public string Id { get; set; }
        public string Special_id { get; set; }
    }

Then :

   public List<Account> GetAccountsAsXmlList(string filePath)
   {
     XmlDocument x = new XmlDocument();

     x.Load(filePath);
     List<Account> result = new List<Account>();
     XmlNode currentNode;
     foreach (var accountNode in x.LastChild.FirstChild.ChildNodes)
     {
         currentNode = accountNode as XmlNode;
         result.Add(new Account
         {
             accountXml = currentNode.InnerXml,
             Id = currentNode.Attributes["id"].Value,
             Special_id = currentNode.Attributes["special_id"].Value,
         });
     }
      return result;
 }

Upvotes: 2

jdweng
jdweng

Reputation: 34421

Try this

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

namespace ConsoleApplication37
{
    class Program
    {
        static void Main(string[] args)
        {
            string input =
                "<?xml version=\"1.0\"?>" +
                "<accountlist>" +
                  "<main>" +
                    "<account id=\"1\" special_id=\"4923959\">" +
                      "<username>Adam</username>" +
                      "<motto>" +
                        "Hello Everyone>" +
                        "<money>1004</money>" +
                        "<friends>394</friends>" +
                        "<rareid>9</rareid>" +
                        "<mission>10</mission>" +
                      "</motto>" +
                      "</account>" +
                  "</main>" +
                "</accountlist>";

            XDocument doc = XDocument.Parse(input);

            var results = doc.Descendants("accountlist").Select(x => new {
                id = x.Element("main").Element("account").Attribute("id").Value,
                special_id = x.Element("main").Element("account").Attribute("special_id").Value,
                username = x.Element("main").Element("account").Element("username").Value,
                motto = x.Element("main").Element("account").Element("motto").FirstNode.ToString(),
                money = x.Element("main").Element("account").Element("motto").Element("money").Value,
                friends = x.Element("main").Element("account").Element("motto").Element("friends").Value,
                rareid = x.Element("main").Element("account").Element("motto").Element("rareid").Value,
                mission = x.Element("main").Element("account").Element("motto").Element("mission").Value,
            }).ToList();

        }
    }
}

Upvotes: 0

Jon G St&#248;dle
Jon G St&#248;dle

Reputation: 3904

You'll have to use Descendants instead of Elements:

List<string> list = doc.Root.Descendants("account").Descendants()
                   .Select(element => element.Value)
                   .ToList();

Elements only returns child elements of the element (in case of the root element this means <main>).
Descendants returns the entire tree inside the element.

Also: You'll have to fix the tag <motto>Hello Everyone> to <motto>Hello Everyone</motto>

Upvotes: 6

greenfeet
greenfeet

Reputation: 677

Use XPath to get the account element first:

using System.Xml.XPath;    

XDocument doc = XDocument.Parse(xml);

foreach(var account in doc.XPathSelectElements("accountlist/main/account")){
        List<string> list = account.Descendants()
                       .Select(element => element.Value)
                       .ToList();
}

Upvotes: 2

Related Questions