16

How can I transform the following XML into a List<string> or String[]:

<Ids>
  <id>1</id>
  <id>2</id>
</Ids>
GEOCHET
  • 21,119
  • 15
  • 74
  • 98
Henry B
  • 7,947
  • 10
  • 42
  • 46
  • As Rich's answer implies, your answer is somewhat ambiguous. Could you say what you want the list to contain. Is it the IDs ("1" and "2" from your example) by any chance? – Jon Skeet Jun 05 '09 at 17:33
  • Your answer is exactly what I wanted thank you, although I would like to list more than one as the correct answer I cannot but yours is the one I used. – Henry B Jun 12 '09 at 15:24

8 Answers8

48

It sounds like you're more after just parsing rather than full XML serialization/deserialization. If you can use LINQ to XML, this is pretty easy:

using System;
using System.Linq;
using System.Xml.Linq;

public class Test
{
    static void Main()
    {
        string xml = "<Ids><id>1</id><id>2</id></Ids>";

        XDocument doc = XDocument.Parse(xml);

        var list = doc.Root.Elements("id")
                           .Select(element => element.Value)
                           .ToList();

        foreach (string value in list)
        {
            Console.WriteLine(value);
        }
    }
}

In fact the call to Elements could omit the argument as there are only id elements, but I thought I'd demonstrate how to specify which elements you want.

Likewise I'd normally not bother calling ToList unless I really needed a List<string> - without it, the result is IEnumerable<string> which is fine if you're just iterating over it once. To create an array instead, use ToArray.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
18

Here is a way using XmlDocument :

// A string containing the XML data
string xml = "<Ids><id>1</id><id>2</id></Ids>";
// The list you want to fill
ArrayList list = new ArrayList();

XmlDocument doc = new XmlDocument();
// Loading from a XML string (use Load() for file)
doc.LoadXml(xml); 
// Selecting node using XPath syntax
XmlNodeList idNodes = doc.SelectNodes("Ids/id");
// Filling the list
foreach (XmlNode node in idNodes)
    list.Add(node.InnerText);
Martin Delille
  • 11,360
  • 15
  • 65
  • 132
  • I think just using ArrayList instead of List would make it 1.x compatible, is there anything else in there that is 2.0 or greater only? – jjxtra Jun 16 '09 at 01:41
  • Is there really any need to support 1.x? It's just not the common compared to 2.0 and 3.x adoption. – annakata Jun 16 '09 at 12:24
3

With any type of collection. For example :

<Ids> <id>C:\videotest\file0.txt</id> <id>C:\videotest\file1.txt</id> </Ids>

class FileFormat
    {
        public FileFormat(string path)
        {
            this.path = path;
        }
        public string FullPath
        {
            get { return Path.GetFullPath(path); }
        }
        public string FileName
        {
            get { return Path.GetFileName(path); }
        }
        private string path;
    }

List<FileFormat> Files =
        selectedNode
        .Descendants("Ids")
        .Elements("Id")
        .Select(x => new FileFormat(x.Value))
        .Where(s => s.FileName!=string.Empty)
        .ToList();
Dom
  • 41
  • 2
2

the code to convert a string array to xml

items is a string array

items.Aggregate("", (current, x) => current + ("<item>" + x + "</item>"))
ehsan
  • 787
  • 3
  • 13
  • 26
1

This sample will work with the .NET framework 4.0:

into a List

    List<string> Ids= new List<string>(); 
    Ids= selectedNode.Descendants("Ids").Elements("Id").Select(> x=>x.Value).Where(s =>s!= string.Empty).ToList();

into a string []

    string[] Ids= thisNode
                  .Descendants("Ids")          // Ids element
                  .Elements("Id")              // Id elements
                  .Select(x=>x.Value)          // XElement to string
                  .Where(s =>s!= string.Empty) // must be not empty
                  .ToArray();                  // string to string []
Dom
  • 41
  • 2
1

This sample will work with the .NET framework 3.5:

    System.Xml.Linq.XElement element = System.Xml.Linq.XElement.Parse("<Ids>  <id>1</id>  <id>2</id></Ids>");
    System.Collections.Generic.List<string> ids = new System.Collections.Generic.List<string>();
    foreach (System.Xml.Linq.XElement childElement in element.Descendants("id"))
    {
        ids.Add(childElement.Value);
    }
jjxtra
  • 20,415
  • 16
  • 100
  • 140
0

You can use Properties class.

Properties prop = new Properties();
prop.loadFromXML(stream);
Set set = prop.keySet();

You can than access Strings from set for each key. Key is element name of xml.

shake
  • 323
  • 9
  • 23
  • Please state the full name of the Properties class. Which namespace is it in? – John Saunders Jun 16 '09 at 12:27
  • The Properties class represents a persistent set of properties. The Properties can be saved to a stream or loaded from a stream. Each key and its corresponding value in the property list is a string. A property list can contain another property list as its "defaults"; this second property list is searched if the property key is not found in the original property list. – shake Jun 17 '09 at 13:46
0

Here's a way to get typed array from xml by using DataSets. (in this example array of doubles)

DataSet dataSet = new DataSet()
DoubleArray doubles = new DoubleArray(dataSet,0);

dataSet.ReadXml("my.xml");
double a = doubles[0];



public class DoubleArray
{
  DataSet dataSet;
  int tableIndex;
  public DoubleArray(DataSet dataSet,int tableIndex)
  {
    this.dataSet=dataSet;
    this.tableIndex=tableIndex;
  }

  public double this[int index]
  {
    get
    { 
      object ret = dataSet.Tables[tableIndex].Rows[index];
      if(ret is double?) 
        return (ret as double?).Value;
      else
        return double.Parse(ret as string);
    }
    set
    {
      object out = dataSet.Tables[tableIndex].Rows[index];
      if(out is double?)
        dataSet.Tables[tableIndex].Rows[index] = (double?)value;
      else
        dataSet.Tables[tableIndex].Rows[index] = value.ToString();
    }
  }
}

Of course parsing doubles and converting them back to strings all the time might be considered as blasphemy by some programmers... Even for me it was hard not to think about such waste of resources... but I guess sometimes it's better to just turn another away.. don't stress it :)

AareP
  • 2,355
  • 3
  • 21
  • 28