/// <summary> /// Gets the fields from the SIFElement for the specified version of SIF. Only /// the fields that apply to the requested version of SIF will be returned. /// </summary> /// <param name="element"></param> /// <param name="version"></param> /// <returns></returns> public virtual ICollection <SimpleField> GetFields(SifElement element, SifVersion version) { ICollection <SimpleField> fields = element.GetFields(); List <SimpleField> returnValue = new List <SimpleField>(); // remove any fields that do not belong in this version of SIF foreach (SimpleField field in fields) { IElementDef def = field.ElementDef; if (version.CompareTo(def.EarliestVersion) > -1 && version.CompareTo(def.LatestVersion) < 1) { returnValue.Add(field); } } returnValue.Sort(ElementSorter <SimpleField> .GetInstance(version)); return(returnValue); }
/// <summary> /// Parse a SIFDate string, using the appropriate format for the specified version of SIF /// </summary> /// <param name="sifDate">The string XML value to parse into a date</param> /// <param name="version">The SifVersion to us for parsing the string</param> /// <returns>The parsed DateTime</returns> /// <exception cref="AdkTypeParseException">if the date cannot be parsed</exception> public static DateTime?ParseSifDateString(string sifDate, SifVersion version) { if (version.CompareTo(SifVersion.SIF20) >= 0) { return(SifDtd.SIF_2X_FORMATTER.ToDate(sifDate)); } else { return(SifDtd.SIF_1X_FORMATTER.ToDate(sifDate)); } }
/// <summary> /// Reads a SIF_Message element, which sets the version and namespace scope for the rest of the /// xml parsing /// </summary> /// <param name="reader"></param> /// <param name="dtd"></param> /// <param name="zone"></param> /// <param name="flags"></param> /// <param name="defaultVersion"></param> /// <returns></returns> /// <exception cref="OpenADK.Library.AdkParsingException">AdkParsingException is thrown if unable to /// parse the message</exception> /// <exception cref="System.IO.IOException"> IOException is thrown if an error is reported while reading /// the message content</exception> private SifElement ReadSIFMessageElement( XmlReader reader, IDtd dtd, IZone zone, SifParserFlags flags, SifVersion defaultVersion) { SifVersion version = ParseVersion(reader, dtd, zone, flags, defaultVersion); SIF_Message message = new SIF_Message(); // Set the namespace from our working version message.SetXmlns(version.Xmlns); if (version.CompareTo(SifVersion.SIF11) >= 0) { // If we are at SifVersion 1.1 or greater, set the version attribute message.SetVersionAttribute(version.ToString()); } // Advance to the next element if (reader.Read()) { while (reader.NodeType != XmlNodeType.Element) { if (!reader.Read()) { break; } } if (reader.NodeType == XmlNodeType.Element) { SifElement element = ParseElementStream(reader, version, dtd, zone, flags); message.AddChild(element); } } return(message); }
private SifElement ParseElementStream(XmlReader reader, SifVersion version, IDtd dtd, IZone zone, SifParserFlags flags) { bool legacyParse = version.CompareTo(SifVersion.SIF20) < 0; // The current SIFElement being parsed SifElement currentElement = null; // The actual tag name of the current element SifFormatter formatter = Adk.Dtd.GetFormatter(version); reader.MoveToContent(); bool doneParsing = false; while (!(reader.EOF || doneParsing)) { switch (reader.NodeType) { case XmlNodeType.Element: if (reader.LocalName == "SIF_Message") { // Special case for embedded SIF_Message envelopes if ((flags & SifParserFlags.ExpectInnerEnvelope) != 0) { SifElement msgElement = ReadSIFMessageElement(reader, dtd, zone, SifParserFlags.None, version); currentElement.AddChild(msgElement); currentElement = msgElement; } else { throw new AdkParsingException ("Unexpected SIF_Message encountered in parsing", zone); } } else { String xmlName = reader.LocalName; if (xmlName == "Teacher") { Console.WriteLine("Ready to break"); } IElementDef foundDef = LookupElementDef(currentElement, reader, dtd, version, zone); if (foundDef == null) { if (legacyParse) { ParseLegacyXML(reader, version, zone, currentElement, formatter, xmlName); continue; } else if (currentElement != null && currentElement.ElementDef.Name.Equals("XMLData")) { // Parse this into a DOM and set on the XMLData // element XmlReader nestedReader = reader.ReadSubtree(); XmlDocument doc = new XmlDocument(); doc.Load(nestedReader); ((XMLData)currentElement).Xml = doc; continue; } else { String _tag = currentElement != null ? currentElement.ElementDef.Name + "/" + xmlName : xmlName; throw new SifException(SifErrorCategoryCode.Xml, SifErrorCodes.XML_GENERIC_VALIDATION_3, "Unknown element or attribute", _tag + " is not a recognized element of SIF " + version.ToString(), zone); } } if (legacyParse) { IElementVersionInfo evi = foundDef.GetVersionInfo(version); if (evi != null) { IRenderSurrogate rs = evi.GetSurrogate(); if (rs != null) { using (XmlReader subtreeReader = reader.ReadSubtree()) { bool shouldContinue = true; subtreeReader.Read(); try { shouldContinue = rs.ReadRaw(subtreeReader, version, currentElement, formatter); } catch (AdkTypeParseException atpe) { HandleTypeParseException("Unable to parse value: " + atpe.Message, atpe, zone); } subtreeReader.Close(); // advance to the next tag reader.Read(); if (shouldContinue) { continue; } else { throw new SifException(SifErrorCategoryCode.Xml, SifErrorCodes.XML_GENERIC_VALIDATION_3, "Unknown element or attribute", reader.LocalName + " was not able to be parsed by " + rs, zone); } } } } } if (foundDef.Field) { SetFieldValueFromElement (foundDef, currentElement, reader, version, formatter, zone); // Advance to the next tag do { reader.Read(); } while ( !(reader.EOF || reader.NodeType == XmlNodeType.Element || reader.NodeType == XmlNodeType.EndElement)); continue; } else if (reader.IsEmptyElement) { // The .Net XmlReader does not return an EndElement event for // tags with empty content. Therefore, this region of the code is // slightly different from Java ReadSifElementFromElementNode(foundDef, reader, dtd, currentElement, formatter, version, zone); } else { currentElement = ReadSifElementFromElementNode(foundDef, reader, dtd, currentElement, formatter, version, zone); } } break; case XmlNodeType.Text: if (currentElement.ElementDef.HasSimpleContent) { SetFieldValueFromElement(currentElement.ElementDef, currentElement, reader, version, formatter, zone); // The XML Reader cursor is automatically advanced by this method, so we // need to continue on without calling read() continue; } break; case XmlNodeType.EndElement: if (currentElement.Parent != null) { currentElement = (SifElement)currentElement.Parent; while (legacyParse && currentElement.ElementDef.IsCollapsed(version)) { currentElement = (SifElement)currentElement.Parent; } } if (reader.LocalName == "SIF_Message") { // We need to return here. If we let the reader keep reading, and we are reading an embedded // SIF_Message, it will keep parsing the end tags and not let the stack of SifElement objects // propertly unwind. We're done anyway. doneParsing = true; } break; } // Advance the cursor reader.Read(); } if (currentElement == null) { return(null); } else { // Now, unwind and pop off the top element parsed Element top = currentElement; Element current; while ((current = top.Parent) != null) { top = current; } return((SifElement)top); } }
/// <summary> /// Write a SIF element in the version of SIF currently in effect for this /// SIFWriter. /// </summary> /// <param name="o"></param> private void WriteElement(SifElement o) { WriteElement(o, fVersion.CompareTo(SifVersion.SIF20) < 0); }
private SifElement ParseElementStream( XmlReader reader, SifVersion version, IDtd dtd, IZone zone, SifParserFlags flags ) { bool legacyParse = version.CompareTo( SifVersion.SIF20 ) < 0; // The current SIFElement being parsed SifElement currentElement = null; // The actual tag name of the current element SifFormatter formatter = Adk.Dtd.GetFormatter( version ); reader.MoveToContent(); bool doneParsing = false; while ( !(reader.EOF || doneParsing) ) { switch ( reader.NodeType ) { case XmlNodeType.Element: if ( reader.LocalName == "SIF_Message" ) { // Special case for embedded SIF_Message envelopes if ( (flags & SifParserFlags.ExpectInnerEnvelope) != 0 ) { SifElement msgElement = ReadSIFMessageElement( reader, dtd, zone, SifParserFlags.None, version ); currentElement.AddChild( msgElement ); currentElement = msgElement; } else { throw new AdkParsingException ( "Unexpected SIF_Message encountered in parsing", zone ); } } else { String xmlName = reader.LocalName; if( xmlName == "Teacher" ) { Console.WriteLine( "Ready to break" ); } IElementDef foundDef = LookupElementDef( currentElement, reader, dtd, version, zone ); if (foundDef == null) { if (legacyParse) { ParseLegacyXML(reader, version, zone, currentElement, formatter, xmlName); continue; } else if (currentElement != null && currentElement.ElementDef.Name.Equals("XMLData")) { // Parse this into a DOM and set on the XMLData // element XmlReader nestedReader = reader.ReadSubtree(); XmlDocument doc = new XmlDocument(); doc.Load( nestedReader ); ((XMLData)currentElement).Xml = doc; continue; } else { String _tag = currentElement != null ? currentElement.ElementDef.Name + "/" + xmlName : xmlName; throw new SifException( SifErrorCategoryCode.Xml, SifErrorCodes.XML_GENERIC_VALIDATION_3, "Unknown element or attribute", _tag + " is not a recognized element of SIF " + version.ToString(), zone); } } if ( legacyParse ) { IElementVersionInfo evi = foundDef.GetVersionInfo( version ); if (evi != null) { IRenderSurrogate rs = evi.GetSurrogate(); if (rs != null) { using (XmlReader subtreeReader = reader.ReadSubtree()) { bool shouldContinue = true; subtreeReader.Read(); try { shouldContinue = rs.ReadRaw( subtreeReader, version, currentElement, formatter ); } catch ( AdkTypeParseException atpe ) { HandleTypeParseException( "Unable to parse value: " + atpe.Message, atpe, zone ); } subtreeReader.Close(); // advance to the next tag reader.Read(); if ( shouldContinue ) { continue; } else { throw new SifException( SifErrorCategoryCode.Xml, SifErrorCodes.XML_GENERIC_VALIDATION_3, "Unknown element or attribute", reader.LocalName + " was not able to be parsed by " + rs, zone ); } } } } } if ( foundDef.Field ) { SetFieldValueFromElement ( foundDef, currentElement, reader, version, formatter, zone ); // Advance to the next tag do { reader.Read(); } while ( !(reader.EOF || reader.NodeType == XmlNodeType.Element || reader.NodeType == XmlNodeType.EndElement) ); continue; } else if ( reader.IsEmptyElement ) { // The .Net XmlReader does not return an EndElement event for // tags with empty content. Therefore, this region of the code is // slightly different from Java ReadSifElementFromElementNode( foundDef, reader, dtd, currentElement, formatter, version, zone ); } else { currentElement = ReadSifElementFromElementNode( foundDef, reader, dtd, currentElement, formatter, version, zone ); } } break; case XmlNodeType.Text: if ( currentElement.ElementDef.HasSimpleContent ) { SetFieldValueFromElement( currentElement.ElementDef, currentElement, reader, version, formatter, zone ); // The XML Reader cursor is automatically advanced by this method, so we // need to continue on without calling read() continue; } break; case XmlNodeType.EndElement: if ( currentElement.Parent != null ) { currentElement = (SifElement) currentElement.Parent; while ( legacyParse && currentElement.ElementDef.IsCollapsed( version ) ) { currentElement = (SifElement) currentElement.Parent; } } if ( reader.LocalName == "SIF_Message" ) { // We need to return here. If we let the reader keep reading, and we are reading an embedded // SIF_Message, it will keep parsing the end tags and not let the stack of SifElement objects // propertly unwind. We're done anyway. doneParsing = true; } break; } // Advance the cursor reader.Read(); } if ( currentElement == null ) { return null; } else { // Now, unwind and pop off the top element parsed Element top = currentElement; Element current; while ( (current = top.Parent) != null ) { top = current; } return (SifElement) top; } }
/// <summary> /// Gets the fields from the SIFElement for the specified version of SIF. Only /// the fields that apply to the requested version of SIF will be returned. /// </summary> /// <param name="element"></param> /// <param name="version"></param> /// <returns></returns> public virtual ICollection<SimpleField> GetFields(SifElement element, SifVersion version) { ICollection<SimpleField> fields = element.GetFields(); List<SimpleField> returnValue = new List<SimpleField>(); // remove any fields that do not belong in this version of SIF foreach(SimpleField field in fields ) { IElementDef def = field.ElementDef; if (version.CompareTo(def.EarliestVersion) > -1 && version.CompareTo(def.LatestVersion) < 1) { returnValue.Add( field ); } } returnValue.Sort( ElementSorter<SimpleField>.GetInstance( version ) ); return returnValue; }