no; this is (as stated) using a bespoke class - SimpleXmlReader ; copied
below - use it something like:
using(SimpleXml Reader reader = new SimpleXmlReader ({your chosen ctor})) {
// the code from before
}
Let me know if you have any problems,
Marc
using System;
using System.Xml;
using System.IO;
using System.Collecti ons.Generic;
using System.Text;
namespace Your.Namespace. Xml {
/// <summary>
/// Provides a simple but efficient way of reading typical
/// Xml structures with named (field) attributes or elements
<b>immediatel y</b> underneath
/// named (row) elements
/// </summary>
public sealed class SimpleXmlReader : IDisposable {
private static Dictionary<stri ng, int> GetDictionary(s tring[]
nodeNames) {
int index = 0;
Dictionary<stri ng, int> requiredValues = new Dictionary<stri ng,
int>(nodeNames. Length);
foreach (string nodeName in nodeNames) {
if (!string.IsNull OrEmpty(nodeNam e)) {
// deliberately breaks if duplicated key requested;
value represents
// position in out array
requiredValues. Add(nodeName, index++);
}
}
return requiredValues;
}
/// <summary>
/// Returns the cited node values underneath the current element in
the reader
/// </summary>
/// <param name="reader">T he reader to investigate</param>
/// <param name="nodeNames ">The fields required (prefix attributes
with @)</param>
/// <returns>Arra y of strings, with each value in the corresponding
position to the requested fields</returns>
public static string[] ReadValues(XmlR eader reader, params string[]
nodeNames) {
return ReadValues(read er, GetDictionary(n odeNames));
}
private static string[] ReadValues(XmlR eader reader,
Dictionary<stri ng, int> requiredValues) {
string[] result = new string[requiredValues. Count];
string name;
int index, targetDepth = reader.Depth + 1;
bool isEmpty = reader.IsEmptyE lement;
if(reader.HasAt tributes) {
if (reader.MoveToF irstAttribute() ) { // read attributes
do {
name = "@" + reader.Name;
if (requiredValues .TryGetValue(na me, out index) &&
result[index] == null) {
result[index] = reader.Value;
}
} while (reader.MoveToN extAttribute()) ;
}
}
if (!isEmpty && reader.Read()) {// read sub-elements (note this
progresses the cursor)
while (true) {
int currentDepth = reader.Depth;
if (reader.Depth < targetDepth) {
break; // too shallow: reached end of element
} else if (currentDepth > targetDepth) { // too deep:
only interested in first descendents
reader.Skip();
} else if (reader.NodeTyp e == XmlNodeType.Ele ment) { //
right depth; is it an element?
name = reader.Name;
if (requiredValues .TryGetValue(na me, out index) &&
result[index] == null) {
result[index] =
reader.ReadElem entContentAsStr ing(); // progresses cursor
} else { // not interested
reader.Skip(); // progresses cursor
}
} else if (!reader.Read() ) { // progresses cursor
break; // end of the xml (somehow!)
}
}
}
return result;
}
private Stream _stream;
private readonly bool _leaveStreamOpe n, _leaveReaderOpe n;
/// <summary>
/// Create a SimpleXmlReader from a string
/// </summary>
/// <param name="xmlString ">The xml to load</param>
/// <returns>A new SimpleXmlReader object</returns>
public static SimpleXmlReader Create(string xmlString) {
return new SimpleXmlReader (Encoding.UTF8. GetBytes(xmlStr ing));
}
public SimpleXmlReader (string path) : this(new FileStream(path ,
FileMode.Open), false) { }
public SimpleXmlReader (byte[] data) : this(new MemoryStream(da ta),
false) { }
public SimpleXmlReader (Stream stream) : this(stream, false) { }
public SimpleXmlReader (Stream stream, bool leaveOpen) {
_leaveStreamOpe n = leaveOpen;
_leaveReaderOpe n = false;
_stream = stream;
}
public SimpleXmlReader (XmlReader reader) : this(reader, false) { }
public SimpleXmlReader (XmlReader reader, bool leaveOpen) {
_leaveStreamOpe n = false;
_leaveReaderOpe n = leaveOpen;
_reader = reader;
}
/// <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();
if (_stream != null)
doc.Load(_strea m);
else if (_reader != null)
doc.Load(_reade r);
else
throw new InvalidOperatio nException("No stream/reader to
load from");
return doc;
}
private XmlReader _reader;
public XmlReader Reader {
get {
if (_reader == null) {
XmlReaderSettin gs readerSettings = new
XmlReaderSettin gs();
readerSettings. CloseInput = !_leaveStreamOp en;
readerSettings. IgnoreComments = true;
_reader = XmlReader.Creat e(_stream, readerSettings) ;
}
return _reader;
}
}
/// <summary>
/// Searches through the xml (forwards only) looking for the cited
row-element;
/// for each such found, the requested fields are returned to the
caller
/// </summary>
/// <param name="rowElemen tName">The element to search for (at any
level) </param>
/// <param name="nodeNames ">The fields required (prefix attributes
with @)</param>
/// <returns></returns>
/// <remarks>Note that this searches the xml *while* enumerating -
so only one row
/// is ever in memory at once; this makes for highly efficient
processing</remarks>
public System.Collecti ons.Generic.IEn umerable<string[]>
ReadElements(st ring rowElementName, params string[] valueNodeNames) {
XmlReader reader = Reader; // creates if not already there
Dictionary<stri ng, int> requiredValues =
GetDictionary(v alueNodeNames);
while (reader.ReadToF ollowing(rowEle mentName)) {
yield return ReadValues(read er, requiredValues) ;
}
}
public void Close() {
if (_reader != null) {
if (!_leaveReaderO pen) {
_reader.Close() ;
}
_reader = null;
}
if (_stream != null) {
if (!_leaveStreamO pen) {
_stream.Close() ;
_stream.Dispose ();
}
_stream = null;
}
}
public void Dispose() {
Close();
}
}
}
"CodeRazor" <Co*******@disc ussions.microso ft.com> wrote in message
news:9C******** *************** ***********@mic rosoft.com...
Hi Marc, thanks for your help.
When i tried what you suggested though, i get the error,
"'System.Xml.Xm lTextReader' does not contain a definition for
'ReadElements'"
Are you using an XmlTextReader?
I've sent you an email to your posted address.