Delimiters specified in the interchange. Translator’s x12 module expects standard delimiters to be present in processed data.
We can ‘normalize’ delimiters prior to processing, and revert back if needed after the processing.
We can specify non-standard delimiters in respective vmd file, but on this page we can see alternative approach using simple Lua scripting.
The ISA segment has very strict grammar and we know number of each byte representing specific delimiter.
The data element separator is byte number 4. The component element separator is byte number 105. The segment terminator is the byte that immediately follows the number 105.
Using scripting approach, we can easily compensate for presence of <CR><LF> as Segment Terminator or following Segment Terminator, something that might be tricky if we would be using a VMD file to declare non-standard delimiters.
Personally, I would have chosen to ‘normalize’ every EDI interchange delimiters, as a routine, before processing the content data.
Using the project and sample data from page How to approach X12 parsing, we add functionality.
function normalizeDelimiters(d)
local function ST() -- segment terminator
if d:find('GS') == 107 then
return true
end
return false
end
local function CES() -- component element separator
if d:sub(105,105) == ':' then
return true
end
return false
end
local function DES() -- data element separator
if d:sub(4,4) == '*' then
return true
end
return false
end
if ST() then
d = d:gsub(d:sub(106,106),'~')
else
d = d:gsub(d:sub(106,108),'~')
end
if not CES() then d = d:gsub(d:sub(105,105),':') end
if not DES() then d = d:gsub(d:sub(4,4),'*') end
return d
end
function main()
local function readMyFile(fn)
local f = assert(io.open(fn, 'rb'))
local d = f:read('*a')
f:close()
return d
end
local Data = readMyFile('/Users/levblum/270BlueCrossEdited.edi')
-- Match message delimiters to standard values
Data = normalizeDelimiters(Data)
local In,Name,Warnings = x12.parse{
vmd = 'example/270v3.vmd',
data = Data}
trace(In)
end