views:

1153

answers:

5

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

<Ids>
  <id>1</id>
  <id>2</id>
</Ids>
+16  A: 

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
Downvoters: please explain the vote, otherwise it's not terribly useful.Rich: I'm struggling to see what your edits have done - I suspect we had an edit clash while I was putting in the bit about the array. Have I undone anything from your first edit accidentally? (I've no idea who Sasha is, btw.)
Jon Skeet
@Jon: How can you not see that your code was not formatted at all?
Geoffrey Chetwood
Ah, I'd missed that the using directives weren't formatted. I don't consider that "not formatted at all" though. The bulk was formatted fine, with the using directives on one easy-to-miss line :( Now the class is indented for no obvious reason - will fix...
Jon Skeet
@Jon: If you actually pay attention when looking at it, you will see that with your original formatting you were missing whole lines.
Geoffrey Chetwood
@RichB: Could you point out which line? I didn't have the ToList() call, but that wasn't a formatting issue - I just didn't have it in my original code. (The code is valid without it, but doesn't create a list.) Other than that and the using directives, what was missing?
Jon Skeet
@Jon: Seriously man, just look at the revision history. Your using lines were cut off and all on one line outside the code block.
Geoffrey Chetwood
Um, yes, as I said in the third comment: "I'd missed that the using directives weren't formatted" and "The bulk was formatted fine, with the using directives on one easy-to-miss line :("
Jon Skeet
A: 

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);
    }
John JJ Curtis
This question is just crying out for LINQ though :)
Jon Skeet
Assuming > 2.0, yes.
annakata
+5  A: 

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);
tinmaru
Nice this will work on all versions of the framework!
John JJ Curtis
From 2.0 onwards, of course :)
Jon Skeet
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?
John JJ Curtis
Is there really any need to support 1.x? It's just not the common compared to 2.0 and 3.x adoption.
annakata
A: 

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

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