//param childIndexName may have an integer on the end if >1 sibling with same name (e.g. NTE2) private void ParseReps(XmlElement groupElement, IGroup groupObject, String messageName, String childName, String childIndexName) { IList reps = GetChildElementsByTagName(groupElement, MakeGroupElementName(messageName, childName)); log.Debug("# of elements matching " + MakeGroupElementName(messageName, childName) + ": " + reps.Count); if (groupObject.IsRepeating(childIndexName)) { for (int i = 0; i < reps.Count; i++) { ParseRep((XmlElement)reps[i], groupObject.GetStructure(childIndexName, i)); } } else { if (reps.Count > 0) { ParseRep((XmlElement)reps[0], groupObject.GetStructure(childIndexName, 0)); } if (reps.Count > 1) { String newIndexName = groupObject.addNonstandardSegment(childName); for (int i = 1; i < reps.Count; i++) { ParseRep((XmlElement)reps[i], groupObject.GetStructure(newIndexName, i - 1)); } } } }
/// <summary> /// param childIndexName may have an integer on the end if >1 sibling with same name (e.g. NTE2) /// </summary> /// /// <param name="theElem"> Element describing the. </param> /// <param name="theObj"> the object. </param> private void ParseRep(System.Xml.XmlElement theElem, IStructure theObj) { if (theObj is IGroup) { this.Parse((IGroup)theObj, theElem); } else if (theObj is ISegment) { this.Parse((ISegment)theObj, theElem); } log.Debug("Parsed element: " + theElem.Name); }
/// <summary> Finds a message or segment class by name and version.</summary> /// <param name="name">the segment or message structure name. /// </param> /// <param name="version">the HL7 version. /// </param> /// <param name="type">'message', 'group', 'segment', or 'datatype'. /// </param> private static Type FindClass(string name, string version, ClassType type) { if (ParserBase.ValidVersion(version) == false) { throw new HL7Exception("The HL7 version " + version + " is not recognized", ErrorCode.UNSUPPORTED_VERSION_ID); } // get list of packages to search for the corresponding message class var packages = PackageList(version); // get sub-package for component type var typeString = type.ToString(); var subpackage = typeString.Substring(0, 1).ToUpper() + typeString.Substring(1); // try to load class from each package Type compClass = null; var c = 0; while (compClass == null && c < packages.Count) { try { var p = packages[c]; if (!p.EndsWith(".")) { p = p + "."; } var classNameToTry = p + subpackage + "." + name; classNameToTry = AddAssemblyName(p, classNameToTry); if (Log.DebugEnabled) { Log.Debug("Trying to load: " + classNameToTry); } compClass = Type.GetType(classNameToTry); if (Log.DebugEnabled) { Log.Debug("Loaded: " + classNameToTry + " class: " + compClass); } } catch (Exception) { /* just try next one */ } c++; } return(compClass); }
/// <summary> Populates the given error segment with information from this Exception.</summary> public virtual void populate(ISegment errorSegment) { //make sure it's an ERR if (!errorSegment.GetStructureName().Equals("ERR")) { throw new HL7Exception("Can only populate an ERR segment with an exception -- got: " + errorSegment.GetType().FullName); } int rep = errorSegment.GetField(1).Length; //append after existing reps if (SegmentName != null) { Terser.Set(errorSegment, 1, rep, 1, 1, SegmentName); } if (SegmentRepetition >= 0) { Terser.Set(errorSegment, 1, rep, 2, 1, Convert.ToString(SegmentRepetition)); } if (FieldPosition >= 0) { Terser.Set(errorSegment, 1, rep, 3, 1, Convert.ToString(FieldPosition)); } Terser.Set(errorSegment, 1, rep, 4, 1, Convert.ToString(errCode)); Terser.Set(errorSegment, 1, rep, 4, 3, "hl70357"); Terser.Set(errorSegment, 1, rep, 4, 5, Message); //try to get error condition text try { String desc = TableRepository.Instance.getDescription(357, Convert.ToString(errCode)); Terser.Set(errorSegment, 1, rep, 4, 2, desc); } catch (LookupException e) { ourLog.Debug("Warning: LookupException getting error condition text (are we connected to a TableRepository?)", e); } catch (InvalidOperationException e) { ourLog.Debug("Warning: InvalidOperationException getting error condition text (are we connected to a TableRepository? Is a valid ConnectionString configured?)", e); } }
private static void SetObx2Fallback(IPrimitive obx2, ISegment segment, ParserOptions parserOptions) { if (obx2.Value == null) { if (!(parserOptions.DefaultObx2Type is null)) { Log.Debug($"setting default {segment.GetStructureName()}-{2} type to {parserOptions.DefaultObx2Type}"); obx2.Value = parserOptions.DefaultObx2Type; } } }
/// <summary> Sets the string value of the field specified. See class docs for location spec syntax.</summary> public virtual void Set(System.String spec, System.String value_Renamed) { SupportClass.Tokenizer tok = new SupportClass.Tokenizer(spec, "-", false); ISegment segment = getSegment(tok.NextToken()); int[] ind = getIndices(spec); if (log.DebugEnabled) { log.Debug("Setting " + spec + " seg: " + segment.GetStructureName() + " ind: " + ind[0] + " " + ind[1] + " " + ind[2] + " " + ind[3]); } Set(segment, ind[0], ind[1], ind[2], ind[3], value_Renamed); }
/// <summary> Parses a message string and returns the corresponding Message /// object. Unexpected segments added at the end of their group. /// /// </summary> /// <throws> HL7Exception if the message is not correctly formatted. </throws> /// <throws> EncodingNotSupportedException if the message encoded </throws> /// <summary> is not supported by this parser. /// </summary> protected internal override IMessage DoParse(System.String message, System.String version) { //try to instantiate a message object of the right class MessageStructure structure = GetStructure(message); IMessage m = InstantiateMessage(structure.messageStructure, version, structure.explicitlyDefined); //MessagePointer ptr = new MessagePointer(this, m, getEncodingChars(message)); MessageIterator messageIter = new MessageIterator(m, "MSH", true); FilterIterator.IPredicate segmentsOnly = new AnonymousClassPredicate(this); FilterIterator segmentIter = new FilterIterator(messageIter, segmentsOnly); System.String[] segments = Split(message, segDelim); EncodingCharacters encodingChars = GetEncodingChars(message); for (int i = 0; i < segments.Length; i++) { //get rid of any leading whitespace characters ... if (segments[i] != null && segments[i].Length > 0 && System.Char.IsWhiteSpace(segments[i][0])) { segments[i] = StripLeadingWhitespace(segments[i]); } //sometimes people put extra segment delimiters at end of msg ... if (segments[i] != null && segments[i].Length >= 3) { System.String name = segments[i].Substring(0, (3) - (0)); log.Debug("Parsing segment " + name); messageIter.Direction = name; FilterIterator.IPredicate byDirection = new AnonymousClassPredicate1(name, this); FilterIterator dirIter = new FilterIterator(segmentIter, byDirection); if (dirIter.MoveNext()) { Parse((ISegment)dirIter.Current, segments[i], encodingChars); } } } return(m); }
/* for configurability (maybe to add later, replacing hard-coded options * in nextFromEndOfGroup) ... * public void setSearchLevel(String level) { * if (WHOLE_GROUP.equals(level)) { * this.findUpToFirstRequired = false; * this.findFirstDescendentsOnly = false; * } else if (FIRST_DESCENDENTS_ONLY.equals(level)) { * this.findUpToFirstRequired = false; * this.findFirstDescendentsOnly = true; * } else if (UP_TO_FIRST_REQUIRED.equals(level)) { * this.findUpToFirstRequired = true; * this.findFirstDescendentsOnly = false; * } else { * throw IllegalArgumentException(level + " is not a valid search level. Should be WHOLE_GROUP, etc."); * } * } * * public String getSearchLevel() { * String level = WHOLE_GROUP; * if (this.findFirstDescendentsOnly) { * level = FIRST_DESCENDENTS_ONLY; * } else if (this.findUpTpFirstRequired) { * level = UP_TO_FIRST_REQUIRED; * } * return level; * }*/ /// <summary> Returns true if another object exists in the iteration sequence. </summary> public virtual bool MoveNext() { bool has = true; if (next_Renamed_Field == null) { if (typeof(IGroup).IsAssignableFrom(currentStructure.GetType())) { groupNext((IGroup)currentStructure); } else { IGroup parent = currentStructure.ParentStructure; Index i = getIndex(parent, currentStructure); Position currentPosition = new Position(parent, i); try { if (parent.IsRepeating(i.name) && currentStructure.GetStructureName().Equals(direction)) { nextRep(currentPosition); } else { has = nextPosition(currentPosition, this.direction, this.handleUnexpectedSegments); } } catch (HL7Exception e) { throw new System.ApplicationException("HL7Exception arising from bad index: " + e.Message); } } } log.Debug("MessageIterator.hasNext() in direction " + this.direction + "? " + has); return(has); }
/// <summary> Populates the given Segment object with data from the given XML Element.</summary> /// <throws> HL7Exception if the XML Element does not have the correct name and structure </throws> /// <summary> for the given Segment, or if there is an error while setting individual field values. /// </summary> public virtual void Parse(ISegment segmentObject, XmlElement segmentElement) { SupportClass.HashSetSupport done = new SupportClass.HashSetSupport(); // for (int i = 1; i <= segmentObject.NumFields(); i++) { // String elementName = makeElementName(segmentObject, i); // done.add(elementName); // parseReps(segmentObject, segmentElement, elementName, i); // } XmlNodeList all = segmentElement.ChildNodes; for (int i = 0; i < all.Count; i++) { String elementName = all.Item(i).Name; if (Convert.ToInt16(all.Item(i).NodeType) == (short)XmlNodeType.Element && !done.Contains(elementName)) { done.Add(elementName); int index = elementName.IndexOf('.'); if (index >= 0 && elementName.Length > index) { //properly formatted element String fieldNumString = elementName.Substring(index + 1); int fieldNum = Int32.Parse(fieldNumString); ParseReps(segmentObject, segmentElement, elementName, fieldNum); } else { log.Debug("Child of segment " + segmentObject.GetStructureName() + " doesn't look like a field: " + elementName); } } } //set data type of OBX-5 if (segmentObject.GetType().FullName.IndexOf("OBX") >= 0) { Varies.fixOBX5(segmentObject, Factory); } }