/// <summary>
        /// Lexical analysis of the message
        /// </summary>
        /// <param name="segments">The edi segments.</param>
        /// <param name="envelopes">The edi envelopes.</param>
        /// <param name="interchangeContext">The interchange context.</param>
        /// <returns>The pased edi message.</returns>
        public static Message Analyze(List<string> segments, List<string> envelopes, InterchangeContext interchangeContext)
        {
            // Read the message context from the envelope headers
            var messageContext = new MessageContext(envelopes, interchangeContext);

            // This will read through the grammar and will build an xml

            // Get the grammar from the context
            var messageGrammar = ParseTree.LoadFrom(messageContext.SystemType,
                pt => pt.IsMessage || pt.IsGroup || pt.IsChoice || pt.IsAll || pt.IsLoopOfLoops);
            // Set the position in the grammar
            var lastSegment = messageGrammar.Children.First();

            // Create the xml root of the parsed edi
            var ediXml = ToXml(messageGrammar, interchangeContext);
            // Set the position in the xml
            var lastXElement = ediXml;

            // Iterate trough the segment lines
            foreach (var segment in segments)
            {
                try
                {
                    // Find the next segment grammar
                    var currSeg = lastSegment.FindNextSegment(new SegmentFullName(segment, interchangeContext, messageContext.Format));
                    // Build the segment hierarchy
                    // This will move to the required level up for the segment parents: groups, choices, all and loop of loops,
                    // until another group is reached.
                    var segmentTree = GetSegmentTree(currSeg, lastSegment);
                    // Intersect the grammar with the parsed xml.
                    // The new chunk will be attched to this intersection point.
                    lastXElement = lastXElement.AncestorsAndSelf().Last(xe => xe.Name.LocalName == segmentTree.First().Parent.Name);

                    // Attach each bit
                    foreach (var parseTree in segmentTree)
                    {
                        // Parse if a segment, otherwise convert to xml
                        var element = parseTree.IsSegment
                            ? SegmentParser.ParseLine(parseTree, segment, interchangeContext)
                            : ToXml(parseTree, interchangeContext);

                        // Attach to the xml
                        lastXElement.Add(element);
                        // Set the last attached as the attachment point as we iterate from the top parent to the bottom segment
                        lastXElement = element;
                    }

                    // Reset the position in the grammar
                    lastSegment = currSeg;

                }
                catch (Exception ex)
                {
                    throw new ParserException("Failed at line: " + segment, ex);
                }
            }

            return new Message(ediXml, messageContext);
        }
Exemple #2
0
        /// <summary>
        /// Lexical analysis of the message
        /// </summary>
        /// <param name="segments">The edi segments.</param>
        /// <param name="envelopes">The edi envelopes.</param>
        /// <param name="interchangeContext">The interchange context.</param>
        /// <returns>The passed Edi message.</returns>
        public static Message Analyze(List<string> segments, List<string> envelopes, InterchangeContext interchangeContext)
        {
            // Read the message context from the envelope headers
            var messageContext = new MessageContext(envelopes, interchangeContext);

            // This will read through the grammar and will build an xml

            // Get the grammar from the context
            var messageGrammar = ParseTree.LoadFrom(messageContext.SystemType,
                pt => pt.IsMessage || pt.IsGroup || pt.IsChoice || pt.IsAll || pt.IsLoopOfLoops);
            // Set the position in the grammar
            var lastSegment = messageGrammar.Children.First();

            // Create the xml root of the parsed edi
            var ediXml = ToXml(messageGrammar, interchangeContext);
            // Set the position in the xml
            var lastXElement = ediXml;

            // Iterate trough the segment lines
            foreach (var segment in segments)
            {
                try
                {
                    var segmentContext = new SegmentContext(segment, interchangeContext, messageContext.Format);

                    Logger.Log(string.Format("Segment to find: {0}", segmentContext.ToPropertiesString()));

                    // Jump back to HL segment if needed
                    if (segmentContext.IsJump())
                    {
                        XElement hlParent;
                        if (segmentContext.ParentId != null)
                        {
                            // Parent HL, start right after it
                            hlParent = ediXml.Descendants().Single(d => d.Name.LocalName.StartsWith("S_HL") &&
                                                                      d.Elements().First().Value == segmentContext.ParentId);
                            var hl = messageGrammar.Descendants().Single(pt => pt.Name == hlParent.Name.LocalName);
                            lastSegment = hl.Parent.Children[1];
                        }
                        else
                        {
                            // Root HL, start from it
                            hlParent = ediXml.Descendants().First(d => d.Name.LocalName.StartsWith("S_HL"));
                            var hl = messageGrammar.Descendants().Single(pt => pt.Name == hlParent.Name.LocalName);
                            lastSegment = hl;
                        }
                    }

                    // Find the next segment grammar
                    var currSeg = lastSegment.FindNextSegment(segmentContext);

                    Logger.Log(string.Format("Segment found: {0}", currSeg.Name));

                    // Build the segment hierarchy
                    // This will move to the required level up for the segment parents: groups, choices, all and loop of loops,
                    // until another group is reached.
                    var segmentTree = GetSegmentTree(currSeg, lastSegment);
                    // Intersect the grammar with the parsed XML.
                    // The new chunk will be attached to this intersection point.
                    lastXElement = lastXElement.AncestorsAndSelf().Last(xe => xe.Name.LocalName == segmentTree.First().Parent.Name);

                    // Attach each bit
                    foreach (var parseTree in segmentTree)
                    {
                        // Parse if a segment, otherwise convert to XML
                        var element = parseTree.IsSegment
                            ? SegmentParser.ParseLine(parseTree, segment, interchangeContext)
                            : ToXml(parseTree, interchangeContext);

                        // Attach to the XML
                        lastXElement.Add(element);
                        // Set the last attached as the attachment point as we iterate from the top parent to the bottom segment
                        lastXElement = element;
                    }

                    // Reset the position in the grammar
                    lastSegment = currSeg;
                    //var lastfound = AttachTree(segmentTree, segment, interchangeContext);

                }
                catch (Exception ex)
                {
                    throw new ParserException("Failed at line: " + segment, ex);
                }
            }

            return new Message(ediXml, messageContext);
        }
Exemple #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Message"/> class.
 /// </summary>
 /// <param name="context">Edi xml</param>
 /// <param name="item">Context</param>
 public Message(XElement item, MessageContext context)
 {
     Context = context;
     Item    = item;
 }
        /// <summary>
        /// Parses an edi message
        /// </summary>
        /// <param name="typedMessage">
        /// The Xml edi.
        /// </param>
        protected void CreateSegments(XElement typedMessage)
        {
            // Clear all empty nodes
            typedMessage.Descendants().Where(d => string.IsNullOrEmpty(d.Value)).Remove();
            typedMessage.Descendants().Where(d => string.IsNullOrWhiteSpace(d.Value)).Remove();

            var messageContext = new MessageContext(typedMessage);
            // Get all segments, which are not parents of other segments
            foreach (var segment in typedMessage.Descendants().Where(d => d.Name.LocalName.StartsWith("S_")
                && !d.Elements().Any(e => e.Name.LocalName.StartsWith("S_"))))
            {
                Result.Add(SegmentParser.ParseXml(messageContext.SystemType, segment, InterchangeContext));
            }
        }
Exemple #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Message"/> class.
 /// </summary>
 /// <param name="instance">
 /// Edi object
 /// </param>
 public Message(object instance)
 {
     Context = new MessageContext(instance.GetType());
     Item    = EdiHelper.Serialize(instance);
 }