/// <summary> /// Parse an object from <paramref name="s"/> /// </summary> public object Parse(System.Xml.XmlReader s, DatatypeR2FormatterParseResult result) { PDVFormatter baseFormatter = new PDVFormatter(); baseFormatter.Host = this.Host; var retVal = baseFormatter.ParseAttributes <CO>(s, result); // Process the parts #region Elements if (!s.IsEmptyElement) { int sDepth = s.Depth; string sName = s.Name; s.Read(); QTYFormatter qtyf = new QTYFormatter(); // string Name while (!(s.NodeType == System.Xml.XmlNodeType.EndElement && s.Depth == sDepth && s.Name == sName)) { string oldName = s.Name; // Name try { // Numerator if (s.LocalName == "code" && retVal.Code == null) { var parseResult = Host.Parse(s, typeof(CD <String>)); result.Code = parseResult.Code; result.AddResultDetail(parseResult.Details); retVal.Code = parseResult.Structure as CD <String>; } else if (s.LocalName == "code") { result.AddResultDetail(new NotImplementedResultDetail(ResultDetailType.Warning, "Code can only be assigned once", s.ToString())); } else { qtyf.ParseElementsInline(s, retVal, result); } } catch (MessageValidationException e) { result.AddResultDetail(new ResultDetail(MARC.Everest.Connectors.ResultDetailType.Error, e.Message, e)); } finally { if (s.Name == oldName) { s.Read(); } } } } #endregion // Validate new ANYFormatter().Validate(retVal, s.ToString(), result); return(retVal); }
/// <summary> /// Parse the PQ back into a structure /// </summary> public object Parse(System.Xml.XmlReader s, DatatypeR2FormatterParseResult result) { // Create the base formatter PDVFormatter baseFormatter = new PDVFormatter(); baseFormatter.Host = this.Host; // Read temporary values string tUnit = null; if (s.GetAttribute("unit") != null) { tUnit = s.GetAttribute("unit"); } SET <CodingRationale> tRationale = null; if (s.GetAttribute("codingRationale") != null) { tRationale = Util.Convert <SET <CodingRationale> >(s.GetAttribute("codingRationale")); } // Parse PDV content (only attributes) var retVal = baseFormatter.ParseAttributes <PQ>(s, result); // Set PDV content retVal.Unit = tUnit; retVal.CodingRationale = tRationale; // Process elements // This requires a QTY formatter as QTY elements may be // in the stream as well #region Elements if (!s.IsEmptyElement) { // Prepare a formatter to process QTY elements QTYFormatter qtyFormatter = new QTYFormatter(); qtyFormatter.Host = this.Host; // Exit markers int sDepth = s.Depth; string sName = s.Name; // Translations SET <PQR> translations = new SET <PQR>(); // Read the next element s.Read(); // Read until exit condition is fulfilled while (!(s.NodeType == System.Xml.XmlNodeType.EndElement && s.Depth == sDepth && s.Name == sName)) { string oldName = s.Name; // Name try { if (s.LocalName == "translation") // Format using ED { var hostResult = Host.Parse(s, typeof(PQR)); result.Code = hostResult.Code; result.AddResultDetail(hostResult.Details); translations.Add(hostResult.Structure as PQR); } else { qtyFormatter.ParseElementsInline(s, retVal, result); } } catch (MessageValidationException e) { result.AddResultDetail(new MARC.Everest.Connectors.ResultDetail(MARC.Everest.Connectors.ResultDetailType.Error, e.Message, s.ToString(), e)); } finally { if (s.Name == oldName) { s.Read(); } } } // Set translations if (!translations.IsEmpty) { retVal.Translation = translations; } } #endregion // Validate ANYFormatter anyFormatter = new ANYFormatter(); string pathName = s is XmlStateReader ? (s as XmlStateReader).CurrentPath : s.Name; anyFormatter.Validate(retVal as ANY, pathName, result); // REturn instance return(retVal); }
/// <summary> /// Parse the RTO /// </summary> public object Parse(System.Xml.XmlReader s, DatatypeR2FormatterParseResult result) { // Create the types Type rtoType = typeof(RTO <,>); QTYFormatter baseFormatter = (new QTYFormatter() { Host = this.Host }); // Quantity value, just read into a REAL var qty = baseFormatter.ParseAttributes <REAL>(s, result); // Temporary values IGraphable denominator = null, numerator = null; // Elements // This type is a little different in R2, basically we can't determine the generic // parameters by the XSI Type so we have to parse the num/denom manually, and // ensure that we have both, then we construct the object and set the properties #region Elements if (!s.IsEmptyElement) { int sDepth = s.Depth; string sName = s.Name; s.Read(); // string Name while (!(s.NodeType == System.Xml.XmlNodeType.EndElement && s.Depth == sDepth && s.Name == sName)) { string oldName = s.Name; // Name try { // Numerator if (s.LocalName == "numerator") { var parseResult = Host.Parse(s, GenericArguments[0]); result.Code = parseResult.Code; result.AddResultDetail(parseResult.Details); numerator = parseResult.Structure; } // Denominator else if (s.LocalName == "denominator") { var parseResult = Host.Parse(s, GenericArguments[1]); result.Code = parseResult.Code; result.AddResultDetail(parseResult.Details); denominator = parseResult.Structure; } else { baseFormatter.ParseElementsInline(s, qty, result); } } catch (MessageValidationException e) { result.AddResultDetail(new MARC.Everest.Connectors.ResultDetail(MARC.Everest.Connectors.ResultDetailType.Error, e.Message, e)); } finally { if (s.Name == oldName) { s.Read(); } } } } #endregion try { // Construct the generic type (if possible) Type rtoGenericType = rtoType.MakeGenericType(new Type[] { numerator == null ? typeof(IQuantity) : numerator.GetType(), denominator == null ? typeof(IQuantity) : denominator.GetType() }); // Create an instance of rto from the rtoType object instance = rtoGenericType.GetConstructor(Type.EmptyTypes).Invoke(null); // Get the values from the QTY and copy IQuantity rtoQty = instance as IQuantity; DatatypeR2Formatter.CopyBaseAttributes(qty, rtoQty as ANY); rtoQty.Expression = qty.Expression; rtoQty.OriginalText = qty.OriginalText; rtoQty.UncertainRange = qty.UncertainRange; rtoQty.Uncertainty = qty.Uncertainty; rtoQty.UncertaintyType = qty.UncertaintyType; // rto properties PropertyInfo numeratorProperty = rtoGenericType.GetProperty("Numerator"), denominatorProperty = rtoGenericType.GetProperty("Denominator"); // Set the previously found properties numeratorProperty.SetValue(instance, Util.FromWireFormat(numerator, numeratorProperty.PropertyType), null); denominatorProperty.SetValue(instance, Util.FromWireFormat(denominator, denominatorProperty.PropertyType), null); // Validate ANYFormatter anyFormatter = new ANYFormatter(); string pathName = s is XmlStateReader ? (s as XmlStateReader).CurrentPath : s.Name; anyFormatter.Validate(instance as ANY, pathName, result); return(instance); } catch (Exception e) { result.AddResultDetail(new ResultDetail(ResultDetailType.Error, e.Message, e)); return(null); } }