16

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

<Ids>
  <id>1</id>
  <id>2</id>
</Ids>
2
  • 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? Commented Jun 5, 2009 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. Commented Jun 12, 2009 at 15:24

8 Answers 8

49

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.

Sign up to request clarification or add additional context in comments.

Comments

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);

2 Comments

I think just using ArrayList instead of List<string> would make it 1.x compatible, is there anything else in there that is 2.0 or greater only?
Is there really any need to support 1.x? It's just not the common compared to 2.0 and 3.x adoption.
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();

Comments

2

the code to convert a string array to xml

items is a string array

items.Aggregate("", (current, x) => current + ("<item>" + x + "</item>"))

Comments

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);
    }

1 Comment

This question is just crying out for LINQ though :)
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 []

Comments

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.

2 Comments

Please state the full name of the Properties class. Which namespace is it in?
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.
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 :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.