Comments (6)
Hi Josh,
I'm assuming you have something like parser, result = parser.read(...)
, where parser is a StateMachine
instance.
The second return value from this call will always be Result.failure(...)
because reaching the end of the file is an error to the tokenizer -- it's unknown to the tokenizer if the caller expected this or not. However, it's labeled a non-fatal error: you can test for more serious errors with result.fatal?
, which might happen if the file has invalid delimiters, etc.
The first return value, parser
is the new StateMachine
which points at the last segment of the parse tree constructed by reading the input. You might check parser.empty?
to make sure that the contents of the file were read into the parse tree -- the tokenizer skips past everything until it finds a valid ISA
segment.
from stupidedi.
Here's what I've got...
input = File.open("public/ups/UPSS_06_13_2013_1020110058.DAT", encoding: "ISO-8859-1")
=> #<File:public/ups/UPSS_06_13_2013_1020110058.DAT>
parser, result = parser.read(Stupidedi::Reader.build(input))
=> [#<Stupidedi::Builder::StateMachine:0x3fdf82ffb0a8 ...>, Either.failure("reached end of input before finding ISA segment identifier")]
parser.empty?
=> false
parser.segment
=> Either.success(#<Stupidedi::Zipper::EditedCursor:0x007fbf05ff6358 @node=IEA, @path=root/4/1054, @parent=#<Stupidedi::Zipper::EditedCursor:0x007fbf28739b98 @node=InvalidEnvelopeVal(), @path=root/4, @parent=#<Stupidedi::Zipper::RootCursor:0x007fbf3714b5b0 @node=TransmissionVal(), @path=root>>>)
parser.segment.map(&:node)
=> Either.success(IEA)
parser.segment.map(&:parent).map(&:node)
=> Either.success(InvalidEnvelopeVal())
parser.element(1)
=> Either.failure("invalid segment")
parser.first.map(&:first?)
=> Either.success(true)
parser.next
=> Either.failure("cannot move to next after last segment")
Something just feels...off. I've run through the documentation and tried various methods to access the data and just can't seem to get it.
Maybe I'm doing something wrong?
from stupidedi.
Looks like you just need to rewind the parser to the start of the parse tree -- the #read
method leaves it positioned on the last segment that was parsed (IEA).
Take a look at bin/edi-pp for an example, but parser = parser.first
will give you Either.success(#<Stupidedi::Builder::StateMachine:...>)
, where the parser is positioned at the start. You'll need to use #map
, #tap
, and #flatmap
to manipulate the StateMachine inside the Either wrapper.
Secondly, your document is QM214, which I recently merged into the contrib namespace. You'll need to use config = Stupidedi::Config.contrib
to parse this file -- otherwise you'll see mostly InvalidSegmentVal values in the parse tree. Be sure to pull the latest commits, I fixed a few issues just now.
Since these were contributed by other authors and I don't have the official grammar for this transaction, you probably need to make changes to the grammar. For instance, the grammar in Stupidedi for QM214 doesn't allow MAN
, N1
, or CD3
segments but your document has these. If you need the information contained in these segments, you'll need to find some documentation like this or this from your EDI trading partner. If you don't need those segments, you can probably leave things as-is -- the parser will add InvalidSegmentVal
nodes in their place, which generally are ignored when moving around the parse tree.
-- Kyle
from stupidedi.
Gotcha! Okay, getting there. One more question...how do I select the second of a duplicate element?
For example, there's this segment:
ST|214|000056390~
B10|0|0|UPSN~
L11|QVD|TN|O4~
L11|1Z6VX489YN03534815|2I~
N1|SH|NA|25|6VX489~
N1|BT||25|6VX489|01~
LX|1~
AT7|X8|AJ|||20130613|003551|LT~
AT7|||AB|BG|20130613~
L11|2U-UPS WILL ATTEMPT DELIVERY|REC|KAGE WILL NOT BE TRANSFERRED T~
MAN|CP|E1|PITTSBURGH DOWNTOWN|CP|PA|US~
CD3|||R4~
N1|UP|NA~
SE|14|000056390~
Then I do this:
a.flatmap{|m| m.find(:GS) }.flatmap{|m| m.find(:ST) }.tap do |m|
el(m.find(:L11), 3){|e| puts "Transaction Reference Number: #{e}" }
el(m.find(:L11)){|e| puts "Tracking Number: #{e}" }
end
That first L11
works correctly (and pulls O4
). But I want to get the next L11
to retrieve 1Z6VX489YN03534815
(Really appreciate your help so far!)
from stupidedi.
It seems like the second element of L11
specifies which "type" of L11
it is, so I would probably do something like this, since TN
or 2I
probably mean something specific and you'll want to act on them differently:
el(m.find(:L11, nil, "TN"), 3){|e| ... }
el(m.find(:L11, nil, "2I"), 3){|e| ... }
You'll need to check specs for QM 214 to be certain, but usually that's how these documents work. If you can have many L11*...*TN
segments or many L11*..*2I
segments in a row, or if the second element is not a qualifier, you should do something like this:
# Loop through each L11 sequentially
m.iterate(:L11) do |l11|
el(l11, 3){|el| ... }
end
from stupidedi.
I've also added a method #sequence
which isn't documented yet. It's just shorthand for chaining multiple #find
calls. Here's an example:
a.flatmap{|m| m.sequence(:GS, :ST) }.tap do |m|
...
end
from stupidedi.
Related Issues (20)
- iterating over files with multiple ISAs HOT 3
- Doesn't handle arbitrarily large input files, and never will be able to HOT 5
- Duplicate Keys HOT 3
- Unknown patient gender in 270 causes validation error HOT 2
- value PR is not allowed in element NM101 HOT 2
- Segment ST Does not occur HOT 2
- Parse EDI 850 ERROR HOT 1
- Accept Tempfile in Stupidedi::Reader.build HOT 1
- Segment N1*PR~ cannot be reached
- Parsing an 837 and grabbing segment values HOT 2
- Is there a way to skip validations and build without some of the segments HOT 2
- 004010 version - B3-07 precision doesn't work as intended HOT 2
- value 091 is not allowed in element DTM01 Date/Time Qualifier HOT 2
- TD1 for X12 Release 4010 gets reduced to 2 fields instead of 10 for no reason HOT 1
- 835 - 005010X221A1 - NTE segment error HOT 2
- Stream writing HOT 2
- help wanted: Only the first element is return when iterating a repeated element HOT 2
- Inconsistent floating point output in 834 ICM data HOT 9
- Adding the additional accepted values for a segement HOT 1
- File permissions issue on v1.4.3 HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from stupidedi.