Beispiel #1
0
        public XDocument Parse(TextReader reader)
        {
            var startSegment = string.Concat((char)reader.Read(), (char)reader.Read(), (char)reader.Read());

            //is this a HL7 message?
            if (startSegment != "MSH" && startSegment != "FHS" && startSegment != "BHS")
            {
                throw new XmlException("Not a valid HL7. (HL7 must start with MSH, FHS or BHS)");
            }

            //get the delimiters
            var fieldDelim        = reader.Read();
            var componentDelim    = reader.Read();
            var repetitionSep     = reader.Read();
            var escapeChar        = reader.Read();
            var subcomponentDelim = reader.Read();

            var doc = new XDocument(
                new XElement("HL7")
                );

            string   segmentName            = null;
            XElement segment                = null;
            XElement field                  = null;
            XElement component              = null;
            XElement subComponent           = null;
            int      fieldIndex             = 1;
            int      componentIndex         = 1;
            int      subComponentIndex      = 1;
            bool     isHeader               = true;
            bool     isHeaderWithDelimiters = true;
            string   token                  = null;
            bool     beginEscapeChar        = false;

            // Get the first data element from the file.
            var val = new TokenDelim(startSegment, fieldDelim);

            segmentName = val.Token;
            segment     = new XElement(segmentName);

            doc.Root.Add(segment);

            field = new XElement(segmentName + "." + fieldIndex, (char)fieldDelim);
            segment.Add(field);
            fieldIndex++;
            field = new XElement(segmentName + "." + fieldIndex, string.Concat((char)componentDelim, (char)repetitionSep, (char)escapeChar, (char)subcomponentDelim));
            segment.Add(field);
            fieldIndex++;

            reader.Read();
            val = NextToken(reader, defaultSegmentDelims, fieldDelim, componentDelim, repetitionSep, escapeChar, subcomponentDelim);

            //create a new element with each data token from //the stream.
            while (val.Delimiter >= 0 && val.Delimiter < short.MaxValue)
            {
                if (defaultSegmentDelims.Contains(val.Delimiter))
                {
                    if (subComponent != null)
                    {
                        subComponent = new XElement(segmentName + "." + fieldIndex + "." + componentIndex + "." + subComponentIndex, token + val.Token);
                        component.Add(subComponent);
                    }
                    else if (component != null)
                    {
                        component = new XElement(segmentName + "." + fieldIndex + "." + componentIndex, token + val.Token);
                        field.Add(component);
                    }
                    else if (segment != null)
                    {
                        field = new XElement(segmentName + "." + fieldIndex, token + val.Token);
                        segment.Add(field);
                    }

                    segment           = null;
                    field             = null;
                    fieldIndex        = 1;
                    component         = null;
                    componentIndex    = 1;
                    subComponent      = null;
                    subComponentIndex = 1;

                    token = "";
                }
                else if (val.Delimiter == fieldDelim)
                {
                    if (segment == null)
                    {
                        segmentName = token + val.Token;
                        segment     = new XElement(segmentName);
                        doc.Root.Add(segment);
                        isHeader = headerSegments.Contains(segmentName);
                        isHeaderWithDelimiters = headerSegmentsWithDelimiters.Contains(segmentName);

                        if (isHeaderWithDelimiters)
                        {
                            /*fieldDelim*/
                            reader.Read();
                            /*componentDelim*/
                            reader.Read();
                            /*repetitionSep*/
                            reader.Read();
                            /*escapeChar*/
                            reader.Read();
                            /*subcomponentDelim*/
                            reader.Read();

                            field = new XElement(segmentName + "." + fieldIndex, (char)fieldDelim);
                            segment.Add(field);
                            fieldIndex++;
                            field = new XElement(segmentName + "." + fieldIndex, string.Concat((char)componentDelim, (char)repetitionSep, (char)escapeChar, (char)subcomponentDelim));
                            segment.Add(field);
                        }
                        else
                        {
                            fieldIndex--;
                        }
                    }
                    else
                    {
                        if (fieldIndex > 0)
                        {
                            if (isHeaderWithDelimiters && fieldIndex == 1)
                            {
                                field = new XElement(segmentName + "." + fieldIndex, string.Concat((char)componentDelim, (char)repetitionSep, (char)escapeChar, (char)subcomponentDelim));
                                segment.Add(field);
                            }
                            else if (componentIndex == 1)
                            {
                                field = new XElement(segmentName + "." + fieldIndex, token + val.Token);
                                segment.Add(field);
                            }
                            else
                            {
                                component = new XElement(segmentName + "." + fieldIndex + "." + componentIndex, token + val.Token);
                                field.Add(component);
                            }
                        }
                        component         = null;
                        componentIndex    = 1;
                        subComponent      = null;
                        subComponentIndex = 1;
                    }
                    fieldIndex++;
                    token = "";
                }
                else if (val.Delimiter == componentDelim)
                {
                    if (!isHeader || fieldIndex != 1)
                    {
                        if (componentIndex == 1)
                        {
                            field = new XElement(segmentName + "." + fieldIndex);
                            segment.Add(field);
                        }

                        if (subComponentIndex == 1)
                        {
                            component = new XElement(segmentName + "." + fieldIndex + "." + componentIndex, token + val.Token);
                            field.Add(component);
                        }
                        else
                        {
                            subComponent = new XElement(segmentName + "." + fieldIndex + "." + componentIndex + "." + subComponentIndex, token + val.Token);
                            component.Add(subComponent);
                        }

                        componentIndex++;
                        subComponent      = null;
                        subComponentIndex = 1;
                        token             = "";
                    }
                }
                else if (val.Delimiter == repetitionSep)
                {
                    if (!isHeader || fieldIndex != 1)
                    {
                        component = new XElement(segmentName + "." + fieldIndex + "." + componentIndex, token + val.Token);
                        field.Add(component);

                        componentIndex    = 1;
                        subComponentIndex = 1;
                    }
                }
                else if (val.Delimiter == escapeChar) //TODO:  This just doesn't work
                {
                    beginEscapeChar = !beginEscapeChar;
                    //\Cxxyy\   Single-byte character set escape sequence with two hexadecimal values not converted
                    //\E\       Escape character converted to escape character (e.g., ‘\’)
                    //\F\       Field separator converted to field separator character (e.g., ‘|’)
                    //\H\       Start highlighting not converted
                    //\Mxxyyzz\ Multi-byte character set escape sequence with two or three hexadecimal values (zz is optional) not converted
                    //\N\       Normal text (end highlighting) not converted
                    //\R\       Repetition separator converted to repetition separator character (e.g., ‘~’)
                    //\S\       Component separator converted to component separator character (e.g., ‘^’)
                    //\T\       Subcomponent separator converted to subcomponent separator character (e.g., ‘&’)
                    //\Xdd…\    Hexadecimal data (dd must be hexadecimal characters) converted to the characters identified by each pair of digits
                    //\Zdd…\    Locally defined escape sequence not converted

                    if (!isHeader || fieldIndex != 1)
                    {
                        if (!string.IsNullOrEmpty(val.Token))
                        {
                            if (!beginEscapeChar)
                            {
                                if (val.Token.StartsWith("C"))
                                {
                                }
                                else if (val.Token == "E")
                                {
                                    token += (char)escapeChar;
                                }
                                else if (val.Token == "F")
                                {
                                    token += Convert.ToChar(fieldDelim);        // FrameworkLTC FacID\F\PatID
                                }
                                else if (val.Token == "H")
                                {
                                }
                                else if (val.Token.StartsWith("M"))
                                {
                                }
                                else if (val.Token == "N")
                                {
                                }
                                else if (val.Token == "R")
                                {
                                    token += Convert.ToChar(repetitionSep);
                                }
                                else if (val.Token == "S")
                                {
                                    token += Convert.ToChar(componentDelim);
                                }
                                else if (val.Token == "T")
                                {
                                    token += Convert.ToChar(subcomponentDelim);
                                }
                                else if (val.Token.StartsWith("X"))
                                {
                                }
                                else if (val.Token.StartsWith("Z"))
                                {
                                }
                                else
                                {
                                    token += Convert.ToChar(escapeChar);
                                    token += val.Token;
                                    token += Convert.ToChar(escapeChar);
                                }
                            }
                            else
                            {
                                token += val.Token;
                            }
                        }
                    }
                }
                else if (val.Delimiter == subcomponentDelim)
                {
                    if (!isHeader || fieldIndex != 1)
                    {
                        if (subComponentIndex == 1)
                        {
                            component = new XElement(segmentName + "." + fieldIndex + "." + componentIndex);
                            field.Add(component);
                        }

                        subComponent = new XElement(segmentName + "." + fieldIndex + "." + componentIndex + "." + subComponentIndex, token + val.Token);
                        component.Add(subComponent);
                        subComponentIndex++;
                        token = "";
                    }
                }

                val = NextToken(reader, defaultSegmentDelims, fieldDelim, componentDelim, repetitionSep, escapeChar, subcomponentDelim);
            }

            //add the last token
            if (subComponentIndex > 1 && component != null)
            {
                subComponent = new XElement(segmentName + "." + fieldIndex + "." + componentIndex + "." + subComponentIndex, token + val.Token);
                component.Add(subComponent);
            }
            else if (componentIndex > 1 && field != null)
            {
                component = new XElement(segmentName + "." + fieldIndex + "." + componentIndex, token + val.Token);
                field.Add(component);
            }
            else if (segment != null)
            {
                field = new XElement(segmentName + "." + fieldIndex, token + val.Token);
                segment.Add(field);
            }

            return(doc);
        }
        public XDocument Parse(TextReader reader)
        {
            var startSegment = string.Concat((char)reader.Read(), (char)reader.Read(), (char)reader.Read());

            //is this a HL7 message?
            if (startSegment != "MSH" && startSegment != "FHS" && startSegment != "BHS")
                throw new XmlException("Not a valid HL7. (HL7 must start with MSH, FHS or BHS)");

            //get the delimiters
            var fieldDelim = reader.Read();
            var componentDelim = reader.Read();
            var repetitionSep = reader.Read();
            var escapeChar = reader.Read();
            var subcomponentDelim = reader.Read();

            var doc = new XDocument(
                new XElement("HL7")
            );

            string segmentName = null;
            XElement segment = null;
            XElement field = null;
            XElement component = null;
            XElement subComponent = null;
            int fieldIndex = 1;
            int componentIndex = 1;
            int subComponentIndex = 1;
            bool isHeader = true;
            bool isHeaderWithDelimiters = true;
            string token = null;
            bool beginEscapeChar = false;

            // Get the first data element from the file.
            var val = new TokenDelim(startSegment, fieldDelim);
            segmentName = val.Token;
            segment = new XElement(segmentName);
            doc.Root.Add(segment);

            field = new XElement(segmentName + "." + fieldIndex, (char)fieldDelim);
            segment.Add(field);
            fieldIndex++;
            field = new XElement(segmentName + "." + fieldIndex, string.Concat((char)componentDelim, (char)repetitionSep, (char)escapeChar, (char)subcomponentDelim));
            segment.Add(field);
            fieldIndex++;

            reader.Read();
            val = NextToken(reader, defaultSegmentDelims, fieldDelim, componentDelim, repetitionSep, escapeChar, subcomponentDelim);

            //create a new element with each data token from //the stream.
            while (val.Delimiter >= 0 && val.Delimiter < short.MaxValue)
            {
                if (defaultSegmentDelims.Contains(val.Delimiter))
                {
                    if (subComponent != null)
                    {
                        subComponent = new XElement(segmentName + "." + fieldIndex + "." + componentIndex + "." + subComponentIndex, token + val.Token);
                        component.Add(subComponent);
                    }
                    else if (component != null)
                    {
                        component = new XElement(segmentName + "." + fieldIndex + "." + componentIndex, token + val.Token);
                        field.Add(component);
                    }
                    else if (segment != null)
                    {
                        field = new XElement(segmentName + "." + fieldIndex, token + val.Token);
                        segment.Add(field);
                    }

                    segment = null;
                    field = null;
                    fieldIndex = 1;
                    component = null;
                    componentIndex = 1;
                    subComponent = null;
                    subComponentIndex = 1;

                    token = "";
                }
                else if (val.Delimiter == fieldDelim)
                {
                    if (segment == null)
                    {
                        segmentName = token + val.Token;
                        segment = new XElement(segmentName);
                        doc.Root.Add(segment);
                        isHeader = headerSegments.Contains(segmentName);
                        isHeaderWithDelimiters = headerSegmentsWithDelimiters.Contains(segmentName);

                        if (isHeaderWithDelimiters)
                        {
                            /*fieldDelim*/
                            reader.Read();
                            /*componentDelim*/
                            reader.Read();
                            /*repetitionSep*/
                            reader.Read();
                            /*escapeChar*/
                            reader.Read();
                            /*subcomponentDelim*/
                            reader.Read();

                            field = new XElement(segmentName + "." + fieldIndex, (char)fieldDelim);
                            segment.Add(field);
                            fieldIndex++;
                            field = new XElement(segmentName + "." + fieldIndex, string.Concat((char)componentDelim, (char)repetitionSep, (char)escapeChar, (char)subcomponentDelim));
                            segment.Add(field);
                        }
                        else
                            fieldIndex--;
                    }
                    else
                    {
                        if (fieldIndex > 0)
                        {
                            if (isHeaderWithDelimiters && fieldIndex == 1)
                            {
                                field = new XElement(segmentName + "." + fieldIndex, string.Concat((char)componentDelim, (char)repetitionSep, (char)escapeChar, (char)subcomponentDelim));
                                segment.Add(field);
                            }
                            else if (componentIndex == 1)
                            {
                                field = new XElement(segmentName + "." + fieldIndex, token + val.Token);
                                segment.Add(field);
                            }
                            else
                            {
                                component = new XElement(segmentName + "." + fieldIndex + "." + componentIndex, token + val.Token);
                                field.Add(component);
                            }
                        }
                        component = null;
                        componentIndex = 1;
                        subComponent = null;
                        subComponentIndex = 1;
                    }
                    fieldIndex++;
                    token = "";
                }
                else if (val.Delimiter == componentDelim)
                {
                    if (!isHeader || fieldIndex != 1)
                    {
                        if (componentIndex == 1)
                        {
                            field = new XElement(segmentName + "." + fieldIndex);
                            segment.Add(field);
                        }

                        if (subComponentIndex == 1)
                        {
                            component = new XElement(segmentName + "." + fieldIndex + "." + componentIndex, token + val.Token);
                            field.Add(component);
                        }
                        else
                        {
                            subComponent = new XElement(segmentName + "." + fieldIndex + "." + componentIndex + "." + subComponentIndex, token + val.Token);
                            component.Add(subComponent);
                        }

                        componentIndex++;
                        subComponent = null;
                        subComponentIndex = 1;
                        token = "";
                    }
                }
                else if (val.Delimiter == repetitionSep)
                {
                    if (!isHeader || fieldIndex != 1)
                    {
                        component = new XElement(segmentName + "." + fieldIndex + "." + componentIndex, token + val.Token);
                        field.Add(component);

                        componentIndex = 1;
                        subComponentIndex = 1;
                    }
                }
                else if (val.Delimiter == escapeChar)
                {
                    beginEscapeChar = !beginEscapeChar;
                    //\Cxxyy\ 	Single-byte character set escape sequence with two hexadecimal values not converted
                    //\E\ 	    Escape character converted to escape character (e.g., ‘\’)
                    //\F\ 	    Field separator converted to field separator character (e.g., ‘|’)
                    //\H\ 	    Start highlighting not converted
                    //\Mxxyyzz\ Multi-byte character set escape sequence with two or three hexadecimal values (zz is optional) not converted
                    //\N\ 	    Normal text (end highlighting) not converted
                    //\R\ 	    Repetition separator converted to repetition separator character (e.g., ‘~’)
                    //\S\ 	    Component separator converted to component separator character (e.g., ‘^’)
                    //\T\ 	    Subcomponent separator converted to subcomponent separator character (e.g., ‘&’)
                    //\Xdd…\ 	Hexadecimal data (dd must be hexadecimal characters) converted to the characters identified by each pair of digits
                    //\Zdd…\ 	Locally defined escape sequence not converted
                    if (!isHeader || fieldIndex != 1)
                    {
                        if (!string.IsNullOrEmpty(val.Token))
                        {
                            if (!beginEscapeChar)
                            {
                                if (val.Token.StartsWith("C"))
                                {

                                }
                                else if (val.Token == "E")
                                    token += (char)escapeChar;
                                else if (val.Token == "F")
                                    token += fieldDelim;
                                else if (val.Token == "H")
                                {
                                }
                                else if (val.Token.StartsWith("M"))
                                {

                                }
                                else if (val.Token == "N")
                                {

                                }
                                else if (val.Token == "R")
                                    token += (char)repetitionSep;
                                else if (val.Token == "S")
                                    token += (char)componentDelim;
                                else if (val.Token == "T")
                                    token += (char)subcomponentDelim;
                                else if (val.Token.StartsWith("X"))
                                {

                                }
                                else if (val.Token.StartsWith("Z"))
                                {

                                }
                                else
                                {
                                    token += (char)escapeChar;
                                    token += val.Token;
                                    token += (char)escapeChar;
                                }
                            }
                            else
                            {
                                token += val.Token;
                            }
                        }
                    }
                }
                else if (val.Delimiter == subcomponentDelim)
                {
                    if (!isHeader || fieldIndex != 1)
                    {
                        if (subComponentIndex == 1)
                        {
                            component = new XElement(segmentName + "." + fieldIndex + "." + componentIndex);
                            field.Add(component);
                        }

                        subComponent = new XElement(segmentName + "." + fieldIndex + "." + componentIndex + "." + subComponentIndex, token + val.Token);
                        component.Add(subComponent);
                        subComponentIndex++;
                        token = "";
                    }
                }

                val = NextToken(reader, defaultSegmentDelims, fieldDelim, componentDelim, repetitionSep, escapeChar, subcomponentDelim);
            }

            //add the last token
            if (subComponentIndex > 1 && component != null)
            {
                subComponent = new XElement(segmentName + "." + fieldIndex + "." + componentIndex + "." + subComponentIndex, token + val.Token);
                component.Add(subComponent);
            }
            else if (componentIndex > 1 && field != null)
            {
                component = new XElement(segmentName + "." + fieldIndex + "." + componentIndex, token + val.Token);
                field.Add(component);
            }
            else if (segment != null)
            {
                field = new XElement(segmentName + "." + fieldIndex, token + val.Token);
                segment.Add(field);
            }

            return doc;
        }