kputnam / stupidedi

Ruby API for parsing and generating ASC X12 EDI transactions
BSD 3-Clause "New" or "Revised" License
262 stars 137 forks source link

iterating over files with multiple ISAs #234

Closed alexdean closed 3 years ago

alexdean commented 3 years ago

hello. we've recently started working with a trading partner who is sending multiple ISA/IEA in the same file. we haven't encountered this before, and are having some trouble figuring out how to do this with stupidedi.

i've been picking at this using Navigating as a guide. I think i'm close, but getting a little stumped & hoping someone can set me on the right track.

https://gist.github.com/alexdean/e078db73c82bcc307740973bb39841f7

does this seem like a valid approach? if not, could someone please suggest a better outline for how to achieve this?

thank you very much!

kputnam commented 3 years ago

Yes, you have the right idea! Try this:


# ....
machine, = parser.read(Stupidedi::Reader.build(edi_content))

# After parsing, state machine is positioned at the end of input (last segment), so let's rewind
isa = machine.first

# We can't use isa.iterate(:ISA) here because #iterate always starts searching
# _after_ the cursor position, and would skip the first ISA!
#
# Note: if there was a way to rewind to right before the first segment, iterate
# would work just fine here. Or alternatively, #iterate could be made to search
# right at the current segment. Unfortunately this might break legacy code!
while isa.defined?
  # Unwrap Either<StateMachine> to just a StateMachine. This is safe because we just checked isa.defined?
  isa = isa.fetch

  # Note: this returns an Either<Zipper<Segment>>
  # seg = isa.segment

  # We can use #iterate here because GS occurs somewhere after an ISA, rather than in the same location as the ISA.
  isa.iterate(:GS) do |gs|
    puts extract(gs, 6)
  end

  # Find the next ISA segment, returns Either<StateMachine>
  isa = isa.find(:ISA)
end

puts "no more ISAs found. quitting."
sleep 1
kputnam commented 3 years ago

If this does the trick, please close the issue. Otherwise let me know how I can help!

alexdean commented 3 years ago

seems like that does the trick. thank you very much!