// LAMESPEC: XmlReadMode.Fragment is far from presisely // documented. MS.NET infers schema against this mode. public XmlReadMode ReadXml (XmlReader input, XmlReadMode mode) { switch (input.ReadState) { case ReadState.EndOfFile: case ReadState.Error: case ReadState.Closed: return mode; } // Skip XML declaration and prolog input.MoveToContent (); if (input.EOF) return mode; // FIXME: We need more decent code here, but for now // I don't know the precise MS.NET behavior, I just // delegate to specific read process. switch (mode) { case XmlReadMode.IgnoreSchema: return ReadXmlIgnoreSchema (input, mode, true); case XmlReadMode.ReadSchema: return ReadXmlReadSchema (input, mode, true); } // remaining modes are: Auto, InferSchema, Fragment, Diffgram XmlReader reader = input; int depth = reader.Depth; XmlReadMode result = mode; bool skippedTopLevelElement = false; string potentialDataSetName = null; XmlDocument doc = null; bool shouldReadData = mode != XmlReadMode.DiffGram; bool shouldNotInfer = Tables.Count > 0; switch (mode) { case XmlReadMode.Auto: case XmlReadMode.InferSchema: doc = new XmlDocument (); do { doc.AppendChild (doc.ReadNode (reader)); } while (!reader.EOF && doc.DocumentElement == null); reader = new XmlNodeReader (doc); reader.MoveToContent (); break; case XmlReadMode.DiffGram: if (!(reader.LocalName == "diffgram" && reader.NamespaceURI == XmlConstants.DiffgrNamespace)) goto case XmlReadMode.Auto; break; } switch (mode) { case XmlReadMode.Auto: case XmlReadMode.InferSchema: case XmlReadMode.ReadSchema: if (!(reader.LocalName == "diffgram" && reader.NamespaceURI == XmlConstants.DiffgrNamespace) && !(reader.LocalName == "schema" && reader.NamespaceURI == XmlSchema.Namespace)) potentialDataSetName = reader.LocalName; goto default; case XmlReadMode.Fragment: break; default: if (!(reader.LocalName == "diffgram" && reader.NamespaceURI == XmlConstants.DiffgrNamespace) && !(reader.LocalName == "schema" && reader.NamespaceURI == XmlSchema.Namespace)) { if (!reader.IsEmptyElement) { reader.Read (); reader.MoveToContent (); skippedTopLevelElement = true; } else { switch (mode) { case XmlReadMode.Auto: case XmlReadMode.InferSchema: DataSetName = reader.LocalName; break; } reader.Read (); } } break; } // If schema, then read the first element as schema if (reader.LocalName == "schema" && reader.NamespaceURI == XmlSchema.Namespace) { shouldNotInfer = true; switch (mode) { case XmlReadMode.IgnoreSchema: case XmlReadMode.InferSchema: reader.Skip (); break; case XmlReadMode.Fragment: ReadXmlSchema (reader); break; case XmlReadMode.DiffGram: case XmlReadMode.Auto: if (Tables.Count == 0) { ReadXmlSchema (reader); if (mode == XmlReadMode.Auto) result = XmlReadMode.ReadSchema; } else { // otherwise just ignore and return IgnoreSchema reader.Skip (); result = XmlReadMode.IgnoreSchema; } break; case XmlReadMode.ReadSchema: ReadXmlSchema (reader); break; } } // If diffgram, then read the first element as diffgram if (reader.LocalName == "diffgram" && reader.NamespaceURI == XmlConstants.DiffgrNamespace) { switch (mode) { case XmlReadMode.Auto: case XmlReadMode.IgnoreSchema: case XmlReadMode.DiffGram: XmlDiffLoader DiffLoader = new XmlDiffLoader (this); DiffLoader.Load (reader); if (mode == XmlReadMode.Auto) result = XmlReadMode.DiffGram; shouldReadData = false; break; case XmlReadMode.Fragment: reader.Skip (); break; default: reader.Skip (); break; } } // if schema after diffgram, just skip it. if (!shouldReadData && reader.LocalName == "schema" && reader.NamespaceURI == XmlSchema.Namespace) { shouldNotInfer = true; switch (mode) { default: reader.Skip (); break; case XmlReadMode.ReadSchema: case XmlReadMode.DiffGram: if (Tables.Count == 0) ReadXmlSchema (reader); break; } } if (reader.EOF) return result == XmlReadMode.Auto ? potentialDataSetName != null && !shouldNotInfer ? XmlReadMode.InferSchema : XmlReadMode.IgnoreSchema : result; // Otherwise, read as dataset... but only when required. if (shouldReadData && !shouldNotInfer) { switch (mode) { case XmlReadMode.Auto: if (Tables.Count > 0) goto case XmlReadMode.IgnoreSchema; else goto case XmlReadMode.InferSchema; case XmlReadMode.InferSchema: InferXmlSchema (doc, null); if (mode == XmlReadMode.Auto) result = XmlReadMode.InferSchema; break; case XmlReadMode.IgnoreSchema: case XmlReadMode.Fragment: case XmlReadMode.DiffGram: break; default: shouldReadData = false; break; } } if (shouldReadData) { XmlReader dataReader = reader; if (doc != null) { dataReader = new XmlNodeReader (doc); dataReader.MoveToContent (); } if (reader.NodeType == XmlNodeType.Element) XmlDataReader.ReadXml (this, dataReader, mode); } if (skippedTopLevelElement) { switch (result) { case XmlReadMode.Auto: case XmlReadMode.InferSchema: // DataSetName = potentialDataSetName; // result = XmlReadMode.InferSchema; break; } if (reader.NodeType == XmlNodeType.EndElement) reader.ReadEndElement (); } //* while (input.Depth > depth) input.Read (); if (input.NodeType == XmlNodeType.EndElement) input.Read (); //*/ input.MoveToContent (); return result == XmlReadMode.Auto ? XmlReadMode.IgnoreSchema : result; }
/// <summary> /// Removing this from the IXmlSerializable Implementation because engineers keep exposing the SerialzableDictionary object /// and that cannot be allowed because nobody else can deserialize. It is for persistance only so the logic was moved here. /// </summary> /// <param name="doc">The doc.</param> /// <returns></returns> private IList<string> convertFromXml(XmlDocument doc) { XmlReader reader = new XmlNodeReader(doc); //First check empty element and return if found bool wasEmpty = reader.IsEmptyElement; reader.Read(); if (wasEmpty) return null; IList<string> result = new List<string>(); reader.ReadStartElement(DocumentElement); if (reader.NodeType != XmlNodeType.Element) return result; //Loop through the nodes representing this object in the reader while (reader.NodeType != XmlNodeType.EndElement) { //First try the optimized format //string key = reader.GetAttribute(KEY_ATTRIBUTE); string typeName = reader.GetAttribute(TYPE_ATTRIBUTE); //Read the Xml element representing a new key & value pair reader.ReadStartElement(ITEM_ELEMENT); //if (String.IsNullOrEmpty(key)) //{ // //Key is not being stoed as an attribute - this must be xml in the old format // //KEEP THIS CODE FOR BACKWARDS COMPATIBILITY // //First we need to get the type of the object written to the Xml during serialization so that // //we can create a new serializer that understands how to deserialize this type. // typeName = reader.GetAttribute(TYPE_ATTRIBUTE); // //Read the Xml element representing the key in this key & value pair // reader.ReadStartElement(KEY_ELEMENT); // //Allright now create the serializer and deserialize the defined object type // XmlSerializer keySerializer = new XmlSerializer(typeof(string)); // //key = (string)keySerializer.Deserialize(reader); // if (key == null) // throw new ApplicationException(String.Format("Null key encountered on line {0}", // reader.Depth)); // //Read the end of the key element // reader.ReadEndElement(); //} Type valuetype = (typeName != null ? Type.GetType(typeName) : typeof(object)) ?? typeof(object); //Read the Xml element representing the value in this key & value pair reader.ReadStartElement(VALUE_ELEMENT); //Now create the serialize and deserialize the object type defined from the type attribute XmlSerializer valueSerializer = new XmlSerializer(valuetype); //HACK!!! //Make sure you catch any errors caused by invalid types cannot be deserialized. For example this whole process //kept blowing up because the type ould not be serialized. string value;// = (TValue) valueSerializer.Deserialize(reader); try { value = (string)valueSerializer.Deserialize(reader); } catch (Exception) { value = default(string); //skip top the end of the current element reader.Skip(); } //Read the end of the value element reader.ReadEndElement(); //Now add the deserialized objects to the hashtable. result.Add(value); //Read the end of the element holding the key and value elements if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName == ITEM_ELEMENT) reader.ReadEndElement(); reader.MoveToContent(); } //All done - read the ending element reader.ReadEndElement(); return result; }
/// <summary> /// Parses an IM log file and sends the information to GDS /// </summary> /// <param name="logFile">The IM conversations log file</param> /// <param name="lastIndexed">messages older than this will not be sent to GDS</param> private void ParseAndSendMessages(string logFile, DateTime lastIndexed) { XmlDocument doc = new XmlDocument(); doc.Load(logFile); XmlNodeReader reader = new XmlNodeReader(doc); // reset user and buddy name userName = null; buddyName = null; // Moves the reader to the root element. reader.MoveToContent(); // move to the first message reader.Read(); while(reader.LocalName == "Message") { // check the date of the message - if older skip reader.MoveToAttribute("DateTime"); DateTime messageDateTime = DateTime.Parse(reader.Value); reader.MoveToElement(); // if older than the last indexing time, skip the message if (messageDateTime.CompareTo(lastIndexed) <= 0) { reader.Skip(); continue; } // get message data MSNMessageData messageData = ParseMessageData(reader.ReadOuterXml()); // send this message to GDS for indexing SendMessageData(messageData); } }