I guess it really depends on the size of the data and how you are reading it
(stream, string, etc).
If it is small, then loading it into an XmlDocument and using
SelectNodes("site") then SelectSingleNode("url") etc is probaby the easiest
option. If the data is conceivably large and being erad from a stream, then
your best bet is an xml-reader as it is more efficient - but trickier to use
correctly.
If it helps, I have a fragment of code that can help with *exactly* this
very efficiently using a stream, xml-readers and a custom iterator; in usage
you just do (where "reader" is a SimpleXmlReader (my bespoke class) sat on
top of the data-stream:
listView.BeginUpdate();
try {
listView.Items.Clear();
string rowElementName = "site";
string[] fields = new string[] {"url","lastupdate","check"};
foreach (string[] values in reader.ReadElements(rowElementName, true,
fields)) { // true here means "nested" rather than "attributed" fields
listView.Items.Add(new ListViewItem(values));
rows++;
}
} finally {
listView.EndUpdate();
}
It isn't guaranteed to be fool-proof (all flamings welcome if it improves
the code), but even if you only use it as a starting point it might be
handy.
Marc
SimpleXmlReader:
==========
public sealed class SimpleXmlReader : IDisposable {
public static string[] ReadValues(XmlReader reader, bool nested,
params string[] nodeNames) {
Dictionary<string, int> requiredValues = new Dictionary<string,
int>(nodeNames.Length);
int index = 0;
foreach (string nodeName in nodeNames) {
if (!string.IsNullOrEmpty(nodeName)) {
// deliberately breaks if duplicated key requested;
value represents
// position in out array
requiredValues.Add(nodeName, index++);
}
}
string[] result = new string[nodeNames.Length];
string name;
if (nested) {
int targetDepth = reader.Depth + 1;
bool skipped = false;
while (skipped || reader.Read()) {
skipped = false;
int currentDepth = reader.Depth;
if (reader.Depth < targetDepth) {
break; // reached end of element
}
if (currentDepth > targetDepth) { // too deep
reader.Skip();
skipped = true;
} else if (currentDepth == targetDepth &&
reader.NodeType == XmlNodeType.Element) {
name = reader.Name;
if (requiredValues.TryGetValue(name, out index) &&
index >= 0) {
result[index] =
reader.ReadElementContentAsString();
skipped = true; // since this progresses the
cursor!
requiredValues[name] = -1; // stop reading this
}
}
}
} else {
if (reader.MoveToFirstAttribute()) {
do {
name = reader.Name;
if (requiredValues.TryGetValue(name, out index) &&
index >= 0) {
result[index] = reader.Value;
requiredValues[name] = -1; // stop reading this
}
} while (reader.MoveToNextAttribute());
}
}
return result;
}
private Stream _stream;
private readonly bool _leaveOpen;
private bool LeaveOpen { get { return _leaveOpen; } }
public SimpleXmlReader(string path) : this(new FileStream(path,
FileMode.Open), false) { }
public SimpleXmlReader(byte[] data) : this(new MemoryStream(data),
false) { }
public SimpleXmlReader(Stream stream) : this(stream, false) { }
public SimpleXmlReader(Stream stream, bool leaveOpen) {
_stream = stream;
_leaveOpen = leaveOpen;
}
/// <summary>
/// Reads the stream, returning an XmlDocument
/// </summary>
/// <returns>The XmlDocument of the data</returns>
/// <remarks>This will read to the end of the stream, and
/// cannot be repeated</remarks>
public XmlDocument GetDocument() {
XmlDocument doc = new XmlDocument();
doc.Load(_stream);
return doc;
}
private XmlReader _reader;
public XmlReader Reader {
get {
if (_reader == null) {
XmlReaderSettings readerSettings = new
XmlReaderSettings();
readerSettings.CloseInput = !LeaveOpen;
readerSettings.IgnoreComments = true;
_reader = XmlReader.Create(_stream, readerSettings);
}
return _reader;
}
}
public System.Collections.Generic.IEnumerable<string[]>
ReadElements(string rowElementName, bool nested, params string[]
valueNodeNames) {
XmlReader reader = Reader; // creates if not already there
while (reader.ReadToFollowing(rowElementName)) {
yield return ReadValues(reader, nested, valueNodeNames);
}
}
public void Close() {
if (_stream != null) {
if (!LeaveOpen) _stream.Close();
}
if (_reader != null) {
_reader.Close();
}
}
public void Dispose() {
Close();
if (_stream != null) {
if (!LeaveOpen) _stream.Dispose();
_stream = null;
}
if (_reader != null) {
_reader = null;
}
}
}