module EDI::E

UN/EDIFACT add-ons to EDI module,

Methods for XML support for the UN/EDIFACT module

Author

Heinz W. Werntges, RheinMain University of Applied Sciences, Wiesbaden (edi-ai-dcsm@hs-rm.de)

Copyright © 2006, 2015 Heinz W. Werntges. Licensed under the same terms as Ruby.

$Id: edifact-rexml.rb,v 1.1 2006/08/01 11:14:18 werntges Exp $

This is the XML add-on for UN/EDIFACT module of edi4r (hence ‘::E’)

It leaves all real work to the base classes. Only the UNA information is treated in a special way (as a “Parameter” element of the header) and dealt with here.

UN/EDIFACT add-ons to EDI module,
API to parse and create UN/EDIFACT data

== Author

Heinz W. Werntges, RheinMain University of Applied Sciences, Wiesbaden
(edi-ai-dcsm@hs-rm.de)

== Copyright

Copyright (c) 2006, 2015  Heinz W. Werntges.
Licensed under the same terms as Ruby.

To-do list:
      validate      - add functionality
      charset               - check for valid chars (add UNOD-UNOZ)
      UNT count     - compensate for empty segments which won't show!
      MsgGroup      - improve support
      NDB           - enable support of subsets
      NDB           - support codelists
      SV4           - Support for repetitions
      SV4           - Support for new service segments
      SV4           - Support for I-EDI releases

++

This is the UN/EDIFACT module of edi4r (hence '::E')

It implements EDIFACT versions of classes Interchange, MsgGroup, Message, 
Segment, CDE, and DE in sub-module 'E' of module 'EDI'.

Constants

Illegal_Charset_Patterns

Use pattern for allowed chars of UNOC charset if none given explicitly

Public Class Methods

edi_split( str, s, e, max=0 ) click to toggle source

Utility: Separator method for UN/EDIFACT segments/CDEs

The given string typically comprises an EDIFACT segment or a CDE. We want to split it into its elements and return those in an array. The tricky part is the proper handling of character escaping!

Examples:

CDE = "1234:ABC:567"        --> ['1234','ABC','567']
CDE = "1234::567"           --> ['1234','','567']
CDE = ":::SOMETEXT"         --> ['','','','SOMETEXT']
Seg = "TAG+1++2:3:4+A?+B=C" --> ['TAG','1','','2:3:4','A+B=C']
Seg = "FTX+PUR+1++P:aP?: 120,00 ??:nP?: 100,10??"
                            --> ['FTX','PUR','1','','P:aP?: 120,00 ??:nP?: 100,10??']
   ** OR **             --> ['FTX','PUR','1','','P:aP?: 120,00 ??:nP?: 100,10?']
CDE = "P:aP?: 120,00 ??:nP?: 100,10??"
                            --> ['P','aP: 120,00 ?','nP: 100,10?']

NOTE: This function might be a good candidate for implementation in “C”

Also see: ../../test/test_edi_split.rb

str

String to split

s

Separator char (an Integer)

e

Escape / release char (an Integer)

max

Max. desired number of result items, default = all

Returns:

Array of split results (strings without their terminating separator)
# File lib/edi4r/edifact.rb, line 64
def edi_split( str, s, e, max=0 )
  results, item, start = [], '', 0
  while start < str.length do
    # match_at = index of next separator, or -1 if none found
    match_at = ((start...str.length).find{|i| str[i] == s}) || str.length
    item += str[start...match_at]
    # Count escapes in front of separator. No real separator if odd!
    escapes = count_escapes( item, e )
    if escapes.odd?
      raise EDISyntaxError, "Pending escape char in #{str}" if match_at == str.length
      # (escapes/2+1).times {item.chop!} # chop off duplicate escapes
      item << s # add separator as regular character
    else # even
      # (escapes/2).times {item.chop!}  # chop off duplicate escapes
      results << item
      item = ''
    end
    start = match_at + 1
  end
  #
  # Do not return trailing empty items
  #
  results << item unless item.empty?
  return results if results.empty?
  while results.last.empty?; results.pop; end
  results
end

Private Instance Methods

edi_split( str, s, e, max=0 ) click to toggle source

Utility: Separator method for UN/EDIFACT segments/CDEs

The given string typically comprises an EDIFACT segment or a CDE. We want to split it into its elements and return those in an array. The tricky part is the proper handling of character escaping!

Examples:

CDE = "1234:ABC:567"        --> ['1234','ABC','567']
CDE = "1234::567"           --> ['1234','','567']
CDE = ":::SOMETEXT"         --> ['','','','SOMETEXT']
Seg = "TAG+1++2:3:4+A?+B=C" --> ['TAG','1','','2:3:4','A+B=C']
Seg = "FTX+PUR+1++P:aP?: 120,00 ??:nP?: 100,10??"
                            --> ['FTX','PUR','1','','P:aP?: 120,00 ??:nP?: 100,10??']
   ** OR **             --> ['FTX','PUR','1','','P:aP?: 120,00 ??:nP?: 100,10?']
CDE = "P:aP?: 120,00 ??:nP?: 100,10??"
                            --> ['P','aP: 120,00 ?','nP: 100,10?']

NOTE: This function might be a good candidate for implementation in “C”

Also see: ../../test/test_edi_split.rb

str

String to split

s

Separator char (an Integer)

e

Escape / release char (an Integer)

max

Max. desired number of result items, default = all

Returns:

Array of split results (strings without their terminating separator)
# File lib/edi4r/edifact.rb, line 64
def edi_split( str, s, e, max=0 )
  results, item, start = [], '', 0
  while start < str.length do
    # match_at = index of next separator, or -1 if none found
    match_at = ((start...str.length).find{|i| str[i] == s}) || str.length
    item += str[start...match_at]
    # Count escapes in front of separator. No real separator if odd!
    escapes = count_escapes( item, e )
    if escapes.odd?
      raise EDISyntaxError, "Pending escape char in #{str}" if match_at == str.length
      # (escapes/2+1).times {item.chop!} # chop off duplicate escapes
      item << s # add separator as regular character
    else # even
      # (escapes/2).times {item.chop!}  # chop off duplicate escapes
      results << item
      item = ''
    end
    start = match_at + 1
  end
  #
  # Do not return trailing empty items
  #
  results << item unless item.empty?
  return results if results.empty?
  while results.last.empty?; results.pop; end
  results
end