Пример #1
0
        protected override DocumentPlug ConstructDocumentPlug(ExcelWorksheet schemaWorksheet, int startRow)
        {
            Pluglet rootPluglet = new Pluglet("X12", "GC root Node", PlugletType.Loop, null, 1, -1);

            DocumentPlug documentPlug = new DocumentPlug(rootPluglet, BusinessDomain.FlatFile);

            ReadMetadata(documentPlug, schemaWorksheet);

            string currentLoopName = string.Empty;
            string nextLoopName;

            IPluglet loopPluglet = null;
            IPluglet nextPluglet;
            int      minOccurs, maxOccurs;
            int      row = startRow;

            while ((nextPluglet = GetSegment(schemaWorksheet, ref row, out nextLoopName)) != null)
            {
                // In case of flat file, we do not have loops
                rootPluglet.Children.Add(nextPluglet);
                nextPluglet.Parent = rootPluglet;
            }

            return(documentPlug);
        }
        protected static void FillInMissingChildren(IPluglet segment)
        {
            IList <IPluglet> inputList = segment.Children;
            int origLength             = inputList.Count;

            if (origLength < 2)
            {
                return;
            }

            int visitIndex = 0;

            string prefix;
            int    expectedNumber = GetSequenceNumber(inputList[0].Name, out prefix);

            int visitedNodeNumber;
            int numberOfNodesVisited = 0;

            while (numberOfNodesVisited < origLength)
            {
                visitedNodeNumber = GetSequenceNumber(inputList[visitIndex].Name, out prefix);
                numberOfNodesVisited++;

                //initialize the sequence
                if (visitedNodeNumber >= 0 && expectedNumber < 0)
                {
                    expectedNumber = visitedNodeNumber;
                }

                //if a gap in sequence space is found
                if (visitedNodeNumber > expectedNumber)
                {
                    //fill in the range of numbers from expectedNumber to (visitedNodeNumber-1)
                    for (int fillCount = 0; fillCount <= visitedNodeNumber - 1 - expectedNumber; fillCount++)
                    {
                        string newNodeName = GenerateName(prefix, expectedNumber + fillCount);

                        //more formally consturct a new node here using appropriate constructor
                        IPluglet child = new Pluglet(newNodeName, newNodeName, PlugletType.Data, null, 0, 1, true);
                        child.DataType = new X12_AnDataType("AN", -1, -1);
                        inputList.Insert(visitIndex + fillCount, child);
                        child.Parent = segment;
                    }

                    visitIndex    += visitedNodeNumber - expectedNumber + 1;
                    expectedNumber = visitedNodeNumber + 1;
                }
                else
                {
                    visitIndex++;
                    if (expectedNumber >= 0)
                    {
                        expectedNumber++;
                    }
                }
            }
        }
Пример #3
0
        private void createPluglet(string name, string description, PlugletType type, IPluglet parent, string mandatory, string repeatable)
        {
            int maxOccurs = 1;
            int minOccurs = 1;

            if (repeatable.Equals("Y"))
            {
                maxOccurs = -1;
            }
            if (mandatory == "N")
            {
                minOccurs = 0;
            }
            //if (type == PlugletType.Loop)
            //  maxOccurs = -1;

            Pluglet pluglet = new Pluglet(name, description, type, parent, minOccurs, maxOccurs);
        }
        protected override DocumentPlug ConstructDocumentPlug(ExcelWorksheet schemaWorksheet, int startRow)
        {
            ReadMetadata(schemaWorksheet);

            Pluglet rootPluglet = new Pluglet(
                new PlugletInput()
            {
                Name            = RootNodeName,
                Definition      = "GC root node",
                Type            = PlugletType.Loop,
                Parent          = null,
                IsTagSameAsName = true,                             // for XML spec cert tag is always same as name
            });

            DocumentPlug documentPlug = new DocumentPlug(rootPluglet, BusinessDomain.Xml);

            // Assumption: Element names are not repeated on teh subsequent lines

            IPluglet loopPluglet = null;
            IPluglet nextPluglet;
            int      minOccurs, maxOccurs;
            int      row = startRow;

            // This loop is for level-1 nodes
            try
            {
                while ((nextPluglet = GetNextNode(schemaWorksheet, 1, ref row)) != null)
                {
                    rootPluglet.Children.Add(nextPluglet);
                    nextPluglet.Parent = rootPluglet;
                }
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Row: {0}, Error: {1}", row, ex.Message));
            }

            return(documentPlug);
        }
Пример #5
0
        public void createRootPluglet(Stream stream, string type)
        {
            //path = Path.Combine(RepositoryRoot, @"sources\test\PlugTestHarness\output\Copy of Inbound850ToSuperspecPlug.xlsx");
            //fileInfo = new FileInfo(path);
            using (ExcelPackage pck = new ExcelPackage(stream))
            {
                ExcelWorkbook workBook = pck.Workbook;

                //change worksheet index here for source or target
                if (type.Equals("Source#"))
                {
                    current = workBook.Worksheets[1];
                }
                else
                {
                    current = workBook.Worksheets[2];
                }


                rootPluglet = new Pluglet(retreiveRootName(type), "root Node", (PlugletType)Enum.Parse(typeof(PlugletType), "Segment"), null);

                int rowCount = current.Dimension.End.Row - current.Dimension.Start.Row + 2;

                for (int row = 2; row < rowCount; row++)
                {
                    if (current.Cells[row, NodeTypeIndex].Value == null)
                    {
                        continue;
                    }

                    string name = extractName(row);

                    createPluglet(name, current.Cells[row, DescriptionIndex].Value.ToString(), (PlugletType)Enum.Parse(typeof(PlugletType), current.Cells[row, NodeTypeIndex].Value.ToString()), retreiveParent(current.Cells[row, PathIndex].Value.ToString()), current.Cells[row, MandatoryIndex].Value.ToString(), current.Cells[row, RepeatableIndex].Value.ToString());
                }
            }
        }
Пример #6
0
        private IPluglet GetSegment(ExcelWorksheet schemaWorksheet, ref int row, out string nextLoopName)
        {
            nextLoopName = null;
            // TODO: Handle this in better way
            if (row > schemaWorksheet.Dimension.End.Row)
            {
                return(null);
            }

            // Currently setting Min and Max for segment is hard coded as 0, 1, since these values are not present in excel
            int segmentMinOccur = 0;
            int segmentMaxOccur = 100;

            // First read Segment row
            FlatFileSchemaRow segmentRow = ReadRow(schemaWorksheet, row) as FlatFileSchemaRow;

            while (segmentRow != null && string.IsNullOrWhiteSpace(segmentRow.Segment) == true)
            {
                row++;
                segmentRow = ReadRow(schemaWorksheet, row) as FlatFileSchemaRow;
            }

            if (segmentRow == null)
            {
                return(null);
            }


            nextLoopName    = segmentRow.Loop;
            segmentMinOccur = string.Compare(segmentRow.MandatoryFlag, "Y", true) == 0 ? 1 : 0;
            segmentMaxOccur = string.Compare(segmentRow.MandatoryFlag, "N", true) == 0 ? 0 : 1000;

            IPluglet segment = new Pluglet(segmentRow.Segment, segmentRow.DataElementTag, (PlugletType)Enum.Parse(typeof(PlugletType), "Segment"), null
                                           , segmentMinOccur, segmentMaxOccur);

            if (string.IsNullOrWhiteSpace(segmentRow.Loop) == false)
            {
                segment.Name = segmentRow.Loop;
            }

            ++row;

            IPluglet dataPluglet = null;

            int  minOccurs, maxOccurs;
            bool isIgnore;
            int  tempRow;

            // Now read all data elements till groupping column has some value (indicates new Segment started)
            while ((segmentRow = ReadRow(schemaWorksheet, row) as FlatFileSchemaRow) != null)
            {
                if (string.IsNullOrEmpty(segmentRow.Segment) == false)
                {
                    break;
                }

                // TODO: What about mandatory flag value 'X'?
                minOccurs = string.Compare(segmentRow.MandatoryCode, "M", true) == 0 && string.Compare(segmentRow.MandatoryFlag, "Y", true) == 0 ? 1 : 0;
                maxOccurs = string.Compare(segmentRow.MandatoryFlag, "N", true) == 0 ? 0 : 1;
                isIgnore  = string.Compare(segmentRow.IgnoreFlag, "I", true) == 0;

                dataPluglet = new Pluglet(segmentRow.DataElementTag, segmentRow.DataElementName,
                                          (PlugletType)Enum.Parse(typeof(PlugletType), "Data"), segment, minOccurs, maxOccurs, isIgnore);
                ++row;

                dataPluglet.DataType = ReadDataType(segmentRow, schemaWorksheet, segment.Path, ref row);
            }

            FillInMissingChildren(segment);
            return(segment);
        }
        private IPluglet GetNextNode(ExcelWorksheet schemaWorksheet, int currentLevel, ref int row)
        {
            // TODO: Handle this in better way
            if (row > schemaWorksheet.Dimension.End.Row)
            {
                return(null);
            }

            // Currently setting Min and Max for segment is hard coded as 0, 100, since these values are not present in excel
            int segmentMinOccur = 0;
            int segmentMaxOccur = 100;
            int loopMinOccur    = 0;
            int loopMaxOccur    = 100;

            XmlFileSchemaRow currentRow = ReadRow(schemaWorksheet, row) as XmlFileSchemaRow;
            XmlFileSchemaRow nextRow    = ReadRow(schemaWorksheet, row + 1) as XmlFileSchemaRow;

            IPluglet nextNode  = null;
            IPluglet childNode = null;

            if (nextRow.IsLeafNode)
            {
                segmentMinOccur = string.Compare(currentRow.MandatoryFlag, "Y", true) == 0 ? 1 : 0;
                segmentMaxOccur = string.Compare(currentRow.MandatoryFlag, "N", true) == 0 ? 0 : 1000;
                // If next row contains leaf node then we need to construct segment
                nextNode = new Pluglet(
                    new PlugletInput()
                {
                    Name            = currentRow.ElementName,
                    Definition      = currentRow.ElementName,
                    Type            = PlugletType.Segment,
                    Parent          = null,
                    MinOccurs       = segmentMinOccur,
                    MaxOccurs       = segmentMaxOccur,
                    IsTagSameAsName = true,                 // for XML spec cert tag is always same as name
                });

                IPluglet dataPluglet = null;

                // Now read all data elements
                currentRow = nextRow;
                ++row;
                while (currentRow != null && currentRow.Level == currentLevel + 1)
                {
                    if (currentRow.IsLeafNode)
                    {
                        ++row;
                        int  minOccurs, maxOccurs;
                        bool isIgnore;

                        // TODO: What about mandatory flag value 'X'?
                        minOccurs = string.Compare(currentRow.MandatoryCode, "M", true) == 0 && string.Compare(currentRow.MandatoryFlag, "Y", true) == 0 ? 1 : 0;
                        maxOccurs = string.Compare(currentRow.MandatoryFlag, "N", true) == 0 ? 0 : 1;
                        isIgnore  = string.Compare(currentRow.IgnoreFlag, "I", true) == 0;

                        dataPluglet = new Pluglet(
                            new PlugletInput()
                        {
                            Name            = currentRow.ElementName,
                            Definition      = currentRow.ElementName,
                            Type            = PlugletType.Data,
                            Parent          = nextNode,
                            MinOccurs       = minOccurs,
                            MaxOccurs       = maxOccurs,
                            IsIgnore        = isIgnore,
                            IsTagSameAsName = true,         // for XML spec cert tag is always same as name
                        });

                        dataPluglet.DataType = ReadDataType(currentRow, schemaWorksheet, nextNode.Path, ref row);
                    }
                    else
                    {
                        childNode = GetNextNode(schemaWorksheet, currentLevel + 1, ref row);
                        nextNode.Children.Add(childNode);
                        childNode.Parent = nextNode;
                    }

                    currentRow = ReadRow(schemaWorksheet, row) as XmlFileSchemaRow;
                }
            }
            else
            {
                // If next row contains non-leaf node then we need to construct loop element
                nextNode = new Pluglet(
                    new PlugletInput()
                {
                    Name            = currentRow.ElementName,
                    Definition      = currentRow.ElementName,
                    Type            = PlugletType.Loop,
                    Parent          = null,
                    MinOccurs       = loopMinOccur,
                    MaxOccurs       = loopMaxOccur,
                    IsTagSameAsName = true,                 // for XML spec cert tag is always same as name
                });

                ++row;

                // Read all child elements (level is > current level)
                while (nextRow != null && nextRow.Level > currentLevel)
                {
                    childNode = GetNextNode(schemaWorksheet, currentLevel + 1, ref row);

                    nextNode.Children.Add(childNode);
                    childNode.Parent = nextNode;

                    nextRow = ReadRow(schemaWorksheet, row) as XmlFileSchemaRow;
                }
            }

            // Do we need this for xml cert files?
            // FillInMissingChildren(segment);

            return(nextNode);
        }
Пример #8
0
        private List <string> GetAllPresentValues(List <IDocumentFragment> documentFragments, Pluglet pluglet)
        {
            List <string> presentValues = new List <string>();

            foreach (DocumentFragment documentfragment in documentFragments)
            {
                foreach (DocumentFragment child in documentfragment.Children)
                {
                    if (string.Compare(child.Pluglet.Tag, pluglet.Tag, true) == 0)
                    {
                        presentValues.Add(child.Value);
                        break;
                    }
                }
            }

            return(presentValues);
        }
Пример #9
0
        /// <summary>
        /// Find corrosponding Pluglet for given segmentname and create new segment
        /// </summary>
        /// <param name="segmentName"></param>
        /// <param name="segmentDetails"></param>
        private void CreateAndAddNewSegment(string segmentName, string[] segmentDetails)
        {
            const string firstSegmentName = "ST";

            string   errorMsgs = string.Empty;
            IPluglet nextPluglet;

            string location = "EDIReader.CreateAndAddNewSegment";

            Logger.Debug(location, "Adding {0} segment", segmentName);

            string missingMandatorySegments;

            nextPluglet = CurrentPluglet.GetSegmentPluglet(segmentName, segmentDetails, firstSegmentName, out missingMandatorySegments);

            // First add missing mandatory segment errors
            if (nextPluglet != null && !string.IsNullOrWhiteSpace(missingMandatorySegments))
            {
                string error = string.Format("Missing mandatory segments ({0}) between {1} and {2}"
                                             , missingMandatorySegments, CurrentPluglet.Tag, segmentName);

                if (FatpipeDocumentInst.Errors == null)
                {
                    FatpipeDocumentInst.Errors = new List <string>();
                }
                FatpipeDocumentInst.Errors.Add(error);

                Logger.Error("EDIReader.CreateAndAddNewSegment", EventId.EDIReaderMissingMandatorySegment, "{0} - {1}", GetCurrentPosContext(), error);

                EdiErrorType errorType = nextPluglet.IsIgnore ? EdiErrorType.Warning : EdiErrorType.Error;

                foreach (string segment in missingMandatorySegments.Split(','))
                {
                    Errors.AddSegmentError(segmentName, X12ErrorCode.MandatorySegmentMissingCode
                                           , string.Format("{0} : {1}", X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.MandatorySegmentMissingCode), segment)
                                           , SegmentNumber, this.CurrentSegmentStartPos, this.CurrentSegmentEndPos - 1, errorType);
                }
            }

            if (nextPluglet == null)
            {
                /* //TODO: Revisit following if condition - do we really want to ignore ISA/GS segment missing in schema?
                 * if (segmentName != "ISA" && segmentName != "GS")
                 * {
                 *   errors = string.Format("{0} segment not found in schema after {1}", segmentName, CurrentPluglet.Name);
                 *
                 *   Logger.Error(location, EventId.EDIReaderUnknownSegment, "{0} - {1}", GetCurrentPosContext(), errors);
                 *   Errors.AddSegmentError(segmentName, X12ErrorCode.UnrecognizedSegmentIDCode
                 *       , X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.UnrecognizedSegmentIDCode), SegmentNumber);
                 * }
                 */
                //experimenting with unknown here above is actual
                //IPluglet unknown = new Pluglet("UNRECOGNIZED_SEGMENT", "Unknown Segment", PlugletType.Segment, CurrentPluglet.Parent);
                IPluglet unknown = new Pluglet(
                    new PlugletInput()
                {
                    Name            = "UNRECOGNIZED_SEGMENT",
                    Definition      = "Unknown Segment",
                    Type            = PlugletType.Segment,
                    Parent          = CurrentPluglet.Parent,
                    IsIgnore        = false,
                    AddToParent     = false,
                    IsTagSameAsName = true,
                });

                //  IPluglet x = new Pluglet("child"+i, "Unknown Data", PlugletType.Data, unknown);
                //unknown.Children.Add(x);
                //}

                //DocumentFragment newFragment = unknown.ConstructDocumentFragment(segmentDetails, false, EDIDelimiters, out errors);

                errorMsgs = string.Format("{0} segment not found in schema after {1}", segmentName, CurrentPluglet.Name);

                Errors.AddSegmentError(segmentName, X12ErrorCode.UnrecognizedSegmentIDCode
                                       , X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.UnrecognizedSegmentIDCode), SegmentNumber
                                       , this.CurrentSegmentStartPos, this.CurrentSegmentEndPos - 1, EdiErrorType.Error);

                DocumentFragment newFragment = new DocumentFragment()
                {
                    Pluglet  = unknown,
                    Children = new List <IDocumentFragment>(),
                };

                IPluglet         childPluglet = new Pluglet("Data", "Data", PlugletType.Data, null);
                DocumentFragment child        = new DocumentFragment()
                {
                    Parent         = newFragment,
                    Pluglet        = childPluglet,
                    Children       = null,
                    SequenceNumber = SegmentNumber,
                    StartOffset    = this.CurrentSegmentStartPos,
                    EndOffset      = this.CurrentSegmentEndPos - 1,
                };

                newFragment.Children.Add(child);
                child.Value = CurrentSegment;

                if (newFragment == null)
                {
                    errorMsgs = string.Format("{0} DocumentFragment creation failed. Errors: {1}", segmentName, errorMsgs);
                    Logger.Error(location, EventId.EDIReaderDocFragmentCreation, "{0} - {1}", GetCurrentPosContext(), errorMsgs);
                    //TODO: what should be the code here?
                    //Errors.AddGenericError(segmentName, X12ErrorCode.???
                }
                else
                {
                    ((DocumentFragment)FatpipeDocumentInst.RootFragment).AddDocumentFragment(newFragment);

                    // CurrentPluglet = newFragment.Pluglet;
                }

                //experimenting with unknown here
            }
            else
            {
                if (nextPluglet.RepetitionInfo.MaxOccurs == 0)
                {
                    Errors.AddSegmentError(segmentName, X12ErrorCode.UnexpectedSegmentCode
                                           , string.Format("{0} : {1}", X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.UnexpectedSegmentCode), nextPluglet.Tag)
                                           , SegmentNumber, this.CurrentSegmentStartPos, this.CurrentSegmentEndPos - 1, EdiErrorType.Error);
                }
                else
                {
                    DocumentFragment newFragment = nextPluglet.ConstructDocumentFragment(segmentDetails, false, EDIDelimiters, SegmentNumber,
                                                                                         this.CurrentSegmentStartPos, this.CurrentSegmentEndPos - 1, ref errors, out errorMsgs);

                    if (newFragment == null)
                    {
                        //errorMsgs = string.Format("{0} DocumentFragment creation failed. Errors: {1}", segmentName, errorMsgs);
                        Logger.Error(location, EventId.EDIReaderDocFragmentCreation, "{0} - {1}", GetCurrentPosContext(), errorMsgs);
                        // TODO: Replace UnexpectedSegmentCode with appropriate one
                        Errors.AddGenericError(segmentName, X12ErrorCode.UnexpectedSegmentCode, errorMsgs, SegmentNumber, this.CurrentSegmentStartPos, this.CurrentSegmentEndPos);
                    }
                    else
                    {
                        ((DocumentFragment)FatpipeDocumentInst.RootFragment).AddDocumentFragment(newFragment);

                        CurrentPluglet = newFragment.Pluglet;
                    }
                }
            }

            if (!string.IsNullOrEmpty(errorMsgs))
            {
                if (FatpipeDocumentInst.Errors == null)
                {
                    FatpipeDocumentInst.Errors = new List <string>();
                }
                FatpipeDocumentInst.Errors.Add(errorMsgs);
            }
        }
        private IPluglet GetSegment(ExcelWorksheet schemaWorksheet, ref int row, out string nextLoopName)
        {
            // TODO: Handle this in better way
            if (row > schemaWorksheet.Dimension.End.Row)
            {
                nextLoopName = null;
                return(null);
            }

            // Currently setting Min and Max for segment is hard coded as 0, 1, since these values are not present in excel
            int  segmentMinOccur = 0;
            int  segmentMaxOccur = 100;
            bool isIgnore;

            // First read Segment row
            X12SchemaRow segmentRow = ReadRow(schemaWorksheet, row) as X12SchemaRow;

            nextLoopName = segmentRow.Loop;
            if (nextLoopName == null)
            {
                nextLoopName = string.Empty;
            }

            segmentMinOccur = string.Compare(segmentRow.MandatoryFlag, "Y", true) == 0 ? 1 : 0;
            segmentMaxOccur = string.Compare(segmentRow.MandatoryFlag, "N", true) == 0 ? 0 : 1000;
            isIgnore        = string.Compare(segmentRow.IgnoreFlag, "I", true) == 0;
            IPluglet segment = new Pluglet(segmentRow.Segment, segmentRow.DataElementTag, PlugletType.Segment, null, segmentMinOccur, segmentMaxOccur, isIgnore);

            string xPath = nextLoopName;

            if (string.Compare(xPath, "n/a", true) == 0)
            {
                xPath = nextLoopName = string.Empty;
            }
            if (string.IsNullOrWhiteSpace(xPath) == false)
            {
                xPath = string.Format("X12{0}{1}Loop{2}{3}{4}", segment.PathSeperator, xPath, segment.PathSeperator, segment.Tag, segment.PathSeperator);
            }
            else
            {
                xPath = string.Format("X12{0}{1}{2}", segment.PathSeperator, segment.Tag, segment.PathSeperator);
            }

            ++row;

            IPluglet dataPluglet = null;

            int minOccurs, maxOccurs;

            // Now read all data elements till groupping column has some value (indicates new Segment started)
            while ((segmentRow = ReadRow(schemaWorksheet, row) as X12SchemaRow) != null)
            {
                if (string.IsNullOrEmpty(segmentRow.Grouping) == false)
                {
                    break;
                }

                // TODO: What about mandatory flag value 'X'?
                minOccurs = string.Compare(segmentRow.MandatoryCode, "M", true) == 0 && string.Compare(segmentRow.MandatoryFlag, "Y", true) == 0 ? 1 : 0;
                maxOccurs = string.Compare(segmentRow.MandatoryFlag, "N", true) == 0 ? 0 : 1;
                isIgnore  = string.Compare(segmentRow.IgnoreFlag, "I", true) == 0;

                dataPluglet = new Pluglet(
                    new PlugletInput()
                {
                    Name           = segmentRow.DataElementTag,
                    Definition     = segmentRow.DataElementName,
                    Type           = PlugletType.Data,
                    Parent         = segment,
                    MinOccurs      = minOccurs,
                    MaxOccurs      = maxOccurs,
                    IsIgnore       = isIgnore,
                    IsTriggerField = segmentRow.IsTriggerField
                });
                ++row;

                dataPluglet.DataType = ReadDataType(segmentRow, schemaWorksheet, string.Format("{0}{1}", xPath, segmentRow.DataElementTag), ref row);
            }

            FillInMissingChildren(segment);
            return(segment);
        }
        protected override DocumentPlug ConstructDocumentPlug(ExcelWorksheet schemaWorksheet, int startRow)
        {
            Pluglet rootPluglet = new Pluglet("X12", "GC root Node", PlugletType.Loop, null, 1, -1);

            DocumentPlug documentPlug = new DocumentPlug(rootPluglet, BusinessDomain.X12);

            if (string.IsNullOrWhiteSpace(schemaWorksheet.Name) == false)
            {
                int    documentType;
                string strDocumentType = schemaWorksheet.Name.Substring(0, schemaWorksheet.Name.IndexOf(" "));
                if (int.TryParse(strDocumentType, out documentType) == true)
                {
                    documentPlug.DocumentType = documentType;
                }
            }

            string        currentLoopName = string.Empty;
            string        nextLoopName;
            string        loopName;
            List <string> intermediateLoops = new List <string>();

            IPluglet loopPluglet = null;
            IPluglet nextPluglet;
            IPluglet loopParent;
            int      minOccurs, maxOccurs;
            int      row = startRow;
            int      current, next;

            loopPluglet = rootPluglet;
            while ((nextPluglet = GetSegment(schemaWorksheet, ref row, out nextLoopName)) != null)
            {
                // In case of flat file, we do not have loops
                if (string.IsNullOrEmpty(nextLoopName))
                {
                    rootPluglet.Children.Add(nextPluglet);
                    nextPluglet.Parent = rootPluglet;
                    loopPluglet        = rootPluglet;
                    intermediateLoops.Clear();
                    currentLoopName = nextLoopName;
                }
                else
                {
                    // Check if at least one intermediate loop name is different in next loop
                    if (string.Compare(currentLoopName, nextLoopName) != 0)
                    {
                        loopName = nextLoopName;

                        string[] nextLoops = nextLoopName.Split(new string[] { "->" }, StringSplitOptions.None);

                        // Find first non-matching loop name between intermediateLoops and nextLoops
                        current = next = 0;
                        while (current < intermediateLoops.Count && next < nextLoops.Length)
                        {
                            if (string.Equals(intermediateLoops[current], nextLoops[next], StringComparison.OrdinalIgnoreCase) == false)
                            {
                                break;
                            }
                            current++;
                            next++;
                        }

                        // Get loopParent from current intermediate loops
                        for (int i = intermediateLoops.Count - 1; i >= current; i--)
                        {
                            loopPluglet = loopPluglet.Parent;
                        }

                        loopParent = loopPluglet;

                        // Remove all non-matching intermediate loops
                        int loopsCount = intermediateLoops.Count;
                        for (int i = current; i < loopsCount; i++)
                        {
                            intermediateLoops.RemoveAt(current);
                        }

                        // Add new intermediate loops
                        for (int j = next; j < nextLoops.Length; j++)
                        {
                            // TODO: Any criteria for setting min and max occurs for loop?
                            minOccurs = 1;
                            maxOccurs = 100;

                            // create new loop
                            loopPluglet = new Pluglet(nextLoops[j] + "Loop", "Loop Node", PlugletType.Loop, loopParent, minOccurs, maxOccurs);
                            intermediateLoops.Add(nextLoops[j]);
                            loopParent = loopPluglet;
                        }

                        currentLoopName = nextLoopName;
                    }

                    loopPluglet.Children.Add(nextPluglet);
                    nextPluglet.Parent = loopPluglet;
                }
            }

            return(documentPlug);
        }