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