Heres some sample text that shows how to parse some Xml with XmlTextReader I am trying to demonstrate parsing of attributes, empty nodes and layered nodes all in one go that’s why its quite complex
#region ReadIBVDescriptor Method
private const string ELEMENT_NAME = "IBVDescriptor";
// Parse some xml fragment
// <IBVDescriptor>...</IBVDescriptor>
// On exit the XmlReader is pointing to the
// node immediately following
// the end element node ('</IBVDescriptor>')
public static IBVDescriptor ReadIBVDescriptor(
XmlReader xmlReader)
{
// Move to the next start element
// ('<IBVDescriptor>') if not already there
MoveTo(xmlReader, XmlNodeType.Element);
_Assert((xmlReader.Name == IBVDescriptor_ELEMENT_NAME)
&& (xmlReader.NodeType == XmlNodeType.Element));
int startDepth = xmlReader.Depth;
bool elementIsEmpty = xmlReader.IsEmptyElement;
// PARSE ATTRIBUTES of the descriptor root node
string name = xmlReader.GetAttribute("Name");
string provider = xmlReader.GetAttribute("Provider");
string tmp = xmlReader.GetAttribute("RunningStatus");
// To parse an attribute directly into an 'enum' value
// use the following code pattern
Service.RunningStatuses runningStatus =
(Service.RunningStatuses)Enum.Parse(
typeof(Service.RunningStatuses), tmp);
byte type = byte.Parse(xmlReader.GetAttribute("Type"));
IBVDescriptor descriptor = new IBVDescriptor(
name, provider, runningStatus, type);
if (!elementIsEmpty)
{
xmlReader.Read();
bool endOfDesc = false;
DataService ds = null;
string val;
while (true)
{
// look for the end of the main parent element node
endOfDesc = (xmlReader.Name == ELEMENT_NAME) &&
(xmlReader.NodeType == XmlNodeType.EndElement);
if (endOfDesc)
break;
// PARSE ELEMENT NODES
// Begin Element Processing ''
if (xmlReader.NodeType == XmlNodeType.Element)
{
// Do something with the node
switch (xmlReader.Name)
{
case "DataService":
_Assert(ReferenceEquals(ds, null));
string id = xmlReader.
GetAttribute("DataServiceId");
ds = new DataService(id);
xmlReader.Read();
break;
case "Reserved":
// Interpret an element node. In this
// case we assume it cannot be empty
_Assert(!xmlReader.IsEmptyElement);
val = xmlReader.ReadElementString();
ds.Reserved = val;
break;
case "FieldParity":
// Can read in an entire Xml
// fragment as a string if required
val = xmlReader.ReadOuterXml();
descriptor.FieldParity = val;
break;
case "Authorisation":
// Can devolve complex xml fragments to
other routines
Authorisation val =
XmlHelper.ReadAuthorisation(xmlReader);
descriptor.Authorisation = val;
break;
default: // Whitespace etc.
//TODO_NODE(xmlReader);
// Can use Skip() to ignore unhandled XML
XmlHelper.Skip(xmlReader);
break ;
}
}
else
{
// End Element Processing '</xxx>'
if (xmlReader.NodeType == XmlNodeType.EndElement)
{
if (xmlReader.Name == "DataService")
{
_Assert(!ReferenceEquals(ds, null));
descriptor.AddDataService(ds);
ds = null;
}
}
xmlReader.Read();
}
}
// Use xmlReader.Depth to ensure we are still
_Assert(xmlReader.Depth == startDepth);
_Assert((xmlReader.Name == IELEMENT_NAME) &&
(xmlReader.NodeType == XmlNodeType.EndElement));
xmlReader.Read();
}
return descriptor;
}
#endregion ReadIBVDescriptor Method
// Helper method to skip the next node.
// 'XmlTextReader.Skip()' does not handle
// empty element nodes, ie.
// those of format '<xxx />'
public static void Skip(XmlReader xmlReader)
{
if (xmlReader.IsEmptyElement)
xmlReader.Read();
else
xmlReader.Skip();
}
public static void MoveTo(
XmlReader xmlReader, XmlNodeType nodeType)
{
while (!xmlReader.EOF &&
(xmlReader.NodeType != nodeType) )
{
xmlReader.Read() ;
}
}
No comments:
Post a Comment