internal static T ParseSegment <T>(this SegmentContext segmentContext, Separators separators) { var parseNode = ParseNode.BuldTree(typeof(T), false); parseNode.ParseSegment(segmentContext.Value, separators); return((T)parseNode.ToInstance()); }
/// <summary> /// Converts a message to a collection of EDI segments. /// </summary> /// <param name="item">The message.</param> /// <param name="separators">The EDI separators.</param> /// <returns>The collection of EDI segments.</returns> protected static IEnumerable <string> ToEdi(object item, Separators separators) { var parseTree = ParseNode.BuldTree(item); var segments = parseTree.Descendants().Where(d => d.Prefix == Prefixes.S).Reverse(); return(segments.Select(segment => segment.GenerateSegment(separators))); }
/// <summary> /// Converts a message to a collection of EDI segments. /// </summary> /// <param name="item">The message.</param> /// <param name="separators">The EDI separators.</param> /// <param name="isMessage">If it is a message item.</param> /// <returns>The collection of EDI segments.</returns> protected static IEnumerable <string> ToEdi(object item, Separators separators, bool isMessage = false) { var parseTree = ParseNode.BuldTree(item); var segments = parseTree.Descendants().Where(d => d.Prefix == Prefixes.S).Reverse().ToList(); var result = segments.Select(segment => segment.GenerateSegment(separators)).ToList(); if (!isMessage) { return(result); } var controlNumber = segments.MessageControlNumber(); var trailerTag = item.GetType().FullName.Contains(".X12") ? "SE" : "UNT"; SetTrailer(result, separators, trailerTag, controlNumber); return(result); }
/// <summary> /// Converts an EDI document instance to a collection of EDI segments. /// </summary> /// <param name="item">The EDI document instance.</param> /// <param name="separators">The EDI separators.</param> /// <returns>The collection of EDI segments.</returns> protected static IEnumerable <string> ToEdi(object item, Separators separators) { var parseTree = ParseNode.BuldTree(item); var segments = parseTree.Descendants().Where(d => d.Prefix == Prefixes.S).Reverse().ToList(); var result = segments.Select(segment => segment.GenerateSegment(separators)); if (item is IEdiControl) { return(result); } if (parseTree.EdiName == "TA1") { return(result); } var trailerValues = segments.PullTrailerValues(); return(SetTrailer(result.ToList(), separators, trailerValues.Item2, trailerValues.Item1)); }
internal static void ParseSegment(this ParseNode parseNode, string line, Separators separators, MessageErrorContext errorContext = null) { if (parseNode == null) { throw new ArgumentNullException("parseNode"); } if (String.IsNullOrEmpty(line)) { throw new ArgumentNullException("line"); } if (separators == null) { throw new ArgumentNullException("separators"); } if (parseNode.Prefix != Prefixes.S) { throw new Exception(String.Format("Only segments are supported: {0}", parseNode.Name)); } var dataElementsGrammar = ParseNode.BuldTree(parseNode.Type, false).Children; var dataElements = line.GetDataElements(separators); for (var deIndex = 0; deIndex < dataElements.Length; deIndex++) { var currentDataElement = dataElements[deIndex]; if (String.IsNullOrEmpty(currentDataElement)) { continue; } if (dataElementsGrammar.Count <= deIndex) { if (errorContext != null) { errorContext.Add(parseNode.EdiName, parseNode.IndexInParent() + 1, ErrorCodes.DataElementsTooMany); } throw new ParsingException(ErrorCodes.InvalidInterchangeContent, "Too many data elements in segment.", line, errorContext); } var currentDataElementGrammar = dataElementsGrammar.ElementAt(deIndex); var repetitions = currentDataElementGrammar.IsX12RepetitionSeparator() ? new[] { currentDataElement } : currentDataElement.GetRepetitions(separators); foreach (var repetition in repetitions) { if (String.IsNullOrEmpty(repetition)) { continue; } var childParseNode = parseNode.AddChild(currentDataElementGrammar.Type, currentDataElementGrammar.Name, currentDataElementGrammar.Prefix == Prefixes.D ? repetition.UnEscapeLine(separators) : null); if (currentDataElementGrammar.Prefix != Prefixes.C) { continue; } var componentDataElementsGrammar = currentDataElementGrammar.Children; var componentDataElements = repetition.GetComponentDataElements(separators); for (var cdeIndex = 0; cdeIndex < componentDataElements.Length; cdeIndex++) { var currentComponentDataElement = componentDataElements[cdeIndex]; if (String.IsNullOrEmpty(currentComponentDataElement)) { continue; } var currentComponentDataElementGrammar = componentDataElementsGrammar.ElementAt(cdeIndex); if (componentDataElementsGrammar.Count <= cdeIndex) { if (errorContext != null) { errorContext.Add(parseNode.EdiName, parseNode.IndexInParent() + 1, currentComponentDataElementGrammar.Name, currentDataElementGrammar.IndexInParent() + 1, ErrorCodes.ComponentDataElementsTooMany, currentComponentDataElementGrammar.IndexInParent() + 1, repetitions.ToList().IndexOf(repetition) + 1, currentComponentDataElement); } throw new ParsingException(ErrorCodes.InvalidInterchangeContent, "Too many component data elements.", line, errorContext); } childParseNode.AddChild(currentComponentDataElementGrammar.Type, currentComponentDataElementGrammar.Name, currentComponentDataElement.UnEscapeLine(separators)); } } } }
internal static object Analyze(this List <SegmentContext> segments, Separators separators, MessageContext messageContext) { if (segments == null) { throw new ArgumentNullException("segments"); } if (separators == null) { throw new ArgumentNullException("separators"); } if (messageContext == null) { throw new ArgumentNullException("messageContext"); } var messageGrammar = ParseNode.BuldTree(messageContext.SystemType, true); if (messageGrammar.Prefix != Prefixes.M) { throw new Exception(String.Format("Only messages are supported: {0}", messageGrammar.Name)); } var errorContext = new MessageErrorContext(messageContext.Tag, messageContext.ControlNumber); var segmentPosition = messageGrammar.Children.First(); var instancePosition = new ParseNode(messageContext.SystemType); foreach (var segment in segments) { if (segment.IsControl) { continue; } Logger.Log(String.Format("Segment to match: {0}", segment.LogName)); // Jump back to HL segment if needed if (segment.IsJump) { try { segmentPosition = messageGrammar.JumpToHl(instancePosition.Root(), segment.ParentId); } catch (Exception ex) { errorContext.Add(segment.Name, segments.IndexOf(segment) + 1, ErrorCodes.UnexpectedSegment); throw new ParsingException(ErrorCodes.InvalidInterchangeContent, "Unable to resolve HL.", ex, segment.Value, errorContext); } } var currSeg = segmentPosition.TraverseSegmentsDepthFirst().FirstOrDefault(n => n.IsEqual(segment)); if (currSeg == null) { if (messageGrammar.Descendants().All(d => d.EdiName != segment.Name)) { errorContext.Add(segment.Name, segments.IndexOf(segment) + 1, ErrorCodes.UnrecognizedSegment); throw new ParsingException(ErrorCodes.InvalidInterchangeContent, "Segment is not supported in rules class.", segment.Value, errorContext); } errorContext.Add(segment.Name, segments.IndexOf(segment) + 1, ErrorCodes.UnexpectedSegment); throw new ParsingException(ErrorCodes.InvalidInterchangeContent, "Segment was not in the correct position according to the rules class.", segment.Value, errorContext); } var segmentTree = currSeg.AncestorsToIntersection(segmentPosition); instancePosition = instancePosition.AncestorsAndSelf().Last(nt => nt.Name == segmentTree.First().Parent.Name); foreach (var parseTree in segmentTree) { instancePosition = instancePosition.AddChild(parseTree.Type, parseTree.Type.Name); if (parseTree.Prefix == Prefixes.S) { instancePosition.ParseSegment(segment.Value, separators, errorContext); } } segmentPosition = currSeg; Logger.Log(String.Format("Matched segment: {0}", segmentPosition.Name)); } return(instancePosition.Root().ToInstance()); }