Parsim X12“在膝盖上”

图片 创建与第三方服务和系统主动交互的应用程序时,通常需要与它们进行单向或双向的信息交换

但是,第三方服务通常为此类交互提供单一格式和数据结构。

电子文档管理的这些格式之一是EDI ANSI ASC X12 ,在此给出了相当详细的描述。

KDPV来自此站点


在猫的下面是一个简单的X12解析器算法和Clojure代码,该算法实现了解析器以及处理解析数据的示例。

关于格式的一点


引用以上链接:
ANSI ASC X12(美国国家标准协会认可的标准委员会X12)电子文档交换标准是在70年代开发的,当时电子文档的小尺寸很重要(对于速度为300-1200位/秒的调制解调器),每个字节都必须携带最大的信息。 因此,电子文档的“可读性”被抛弃,取而代之的是“信息密度”。

因此,您不会像XML那样看到任何易于理解的美。 而且尽管该标准允许您创建具有相当复杂的层次结构的文档,但存在块和所谓的循环,但是,甚至没有提供所有块(ISA / GS / ST除外)的关闭标签。 通过kata的链接,想要的人可以详细了解格式的结构和描述,然后我们仅涉及必要的内容。

每种类型的文档都有其自己的模板结构,该模板结构指示各个字段和段的含义和目的,它们的类型和可能的值,以及所需和可选的段和块的列表。 支持模板的版本控制;有关类型和版本号的信息在文档的相应字段中传输。 假定应该使用特定类型文档的模板来对其进行解析和验证。

下面是一个包含几个类型为835的事务的文档的示例(一个声明响应类型的文档),它将演示解析和后续数据处理。

实施例X12
ISA*00* *00* *ZZ*EMEDNYBAT *ZZ*ETIN *140305*0929*^*00501*111111123*0*P*:~ GS*HP*EMED*ETIN*20140301*09304100*111111123*X*005010X221A1~ ST*835*35681~ BPR*I*810.8*C*CHK************20140331~ TRN*1*12345*1512345678~ REF*EV*XYZ CLEARINGHOUSE~ N1*PR*DENTAL OF ABC~ N3*225 MAIN STREET~ N4*CENTERVILLE*PA*17111~ PER*BL*JANE DOE*TE*9005555555~ N1*PE*BAN DDS LLC*FI*999994703~ LX*1~ CLP*7722337*1*226*132**12*119932404007801~ NM1*QC*1*DOE*SANDY****MI*SJD11112~ NM1*82*1*BAN*ERIN****XX*1811901945~ AMT*AU*132~ SVC*AD:D0120*46*25~ DTM*472*20140324~ CAS*CO*131*21~ AMT*B6*25~ SVC*AD:D0220*25*14~ DTM*472*20140324~ CAS*CO*131*11~ AMT*B6*14~ SVC*AD:D0230*22*10~ DTM*472*20140324~ CAS*CO*131*12~ AMT*B6*10~ SVC*AD:D0274*60*34~ DTM*472*20140324~ CAS*CO*131*26~ AMT*B6*34~ SVC*AD:D1110*73*49~ DTM*472*20140324~ CAS*CO*131*24~ AMT*B6*49~ LX*2~ CLP*7722337*1*119*74**12*119932404007801~ NM1*QC*1*DOE*SALLY****MI*SJD11111~ NM1*IL*1*DOE*JOHN****MI*123456~ NM1*82*1*BAN*ERIN****XX*1811901945~ AMT*AU*74~ SVC*AD:D0120*46*25~ DTM*472*20140324~ CAS*CO*131*21~ AMT*B6*25~ SVC*AD:D1110*73*49~ DTM*472*20140324~ CAS*CO*131*24~ AMT*B6*49~ LX*3~ CLP*7722337*1*226*108*24*12*119932404007801~ NM1*QC*1*SMITH*SALLY****MI*SJD11113~ NM1*82*1*BAN*ERIN****XX*1811901945~ AMT*AU*132~ SVC*AD:D0120*46*25~ DTM*472*20140324~ CAS*CO*131*21~ AMT*B6*25~ SVC*AD:D0220*25*0~ DTM*472*20140324~ CAS*PR*3*14~ CAS*CO*131*11~ AMT*B6*14~ SVC*AD:D0230*22*0~ DTM*472*20140324~ CAS*PR*3*10~ CAS*CO*131*12~ AMT*B6*10~ SVC*AD:D0274*60*34~ DTM*472*20140324~ CAS*CO*131*26~ AMT*B6*34~ SVC*AD:D1110*73*49~ DTM*472*20140324~ CAS*CO*131*24~ AMT*B6*49~ LX*4~ CLP*7722337*1*1145*14*902*12*119932404007801~ NM1*QC*1*SMITH*SAM****MI*SJD11116~ NM1*82*1*BAN*ERIN****XX*1811901945~ AMT*AU*14~ SVC*AD:D0220*25*14~ DTM*472*20140324~ CAS*CO*131*11~ AMT*B6*14~ SVC*AD:D2790*940*0~ DTM*472*20140324~ CAS*PR*3*756~ CAS*CO*131*184~ SVC*AD:D2950*180*0~ DTM*472*20140324~ CAS*PR*3*146~ CAS*CO*131*34~ LX*5~ CLP*7722337*1*348*16.8*44.2*12*119932404007801~ NM1*QC*1*JONES*SAM****MI*SJD11122~ NM1*82*1*BAN*ERIN****XX*1811901945~ AMT*AU*28~ SVC*AD:D4342*125*0~ DTM*472*20140313~ CAS*CO*131*125~ SVC*AD:D4381*43*0~ DTM*472*20140313~ CAS*PR*3*33~ CAS*CO*131*10~ SVC*AD:D2950*180*16.8~ DTM*472*20140313~ CAS*PR*3*11.2~ CAS*CO*131*152~ AMT*B6*28~ LX*6~ CLP*7722337*1*226*132**12*119932404007801~ NM1*QC*1*JONES*SALLY****MI*SJD11133~ NM1*82*1*BAN*ERIN****XX*1811901945~ AMT*AU*132~ SVC*AD:D0120*46*25~ DTM*472*20140321~ CAS*CO*131*21~ AMT*B6*25~ SVC*AD:D0220*25*14~ DTM*472*20140321~ CAS*CO*131*11~ AMT*B6*14~ SVC*AD:D0230*22*10~ DTM*472*20140321~ CAS*CO*131*12~ AMT*B6*10~ SVC*AD:D0274*60*34~ DTM*472*20140321~ CAS*CO*131*26~ AMT*B6*34~ SVC*AD:D1110*73*49~ DTM*472*20140321~ CAS*CO*131*24~ AMT*B6*49~ LX*7~ CLP*7722337*1*179*108**12*119932404007801~ NM1*QC*1*DOE*SAM****MI*SJD99999~ NM1*82*1*BAN*ERIN****XX*1811901945~ AMT*AU*108~ SVC*AD:D0120*46*25~ DTM*472*20140324~ CAS*CO*131*21~ AMT*B6*25~ SVC*AD:D0274*60*34~ DTM*472*20140324~ CAS*CO*131*26~ AMT*B6*34~ SVC*AD:D1110*73*49~ DTM*472*20140324~ CAS*CO*131*24~ AMT*B6*49~ LX*8~ CLP*7722337*1*129*82**12*119932404007801~ NM1*QC*1*DOE*SUE****MI*SJD88888~ NM1*82*1*BAN*ERIN****XX*1811901945~ AMT*AU*82~ SVC*AD:D0120*46*25~ DTM*472*20140324~ CAS*CO*131*21~ AMT*B6*25~ SVC*AD:D1120*54*37~ DTM*472*20140324~ CAS*CO*131*17~ AMT*B6*37~ SVC*AD:D1208*29*20~ DTM*472*20140324~ CAS*CO*131*9~ AMT*B6*20~ LX*9~ CLP*7722337*1*221*144**12*119932404007801~ NM1*QC*1*DOE*DONNA****MI*SJD77777~ NM1*82*1*BAN*ERIN****XX*1811901945~ AMT*AU*144~ SVC*AD:D0120*46*25~ DTM*472*20140324~ CAS*CO*131*21~ AMT*B6*25~ SVC*AD:D0330*92*62~ DTM*472*20140324~ CAS*CO*131*30~ AMT*B6*62~ SVC*AD:D1120*54*37~ DTM*472*20140324~ CAS*CO*131*17~ AMT*B6*37~ SVC*AD:D1208*29*20~ DTM*472*20140324~ CAS*CO*131*9~ AMT*B6*20~ SE*190*35681~ GE*1*111111123~ IEA*1*111111123~ 



关于每个块和段的目的的详细描述可以在对这种类型的文档的一般结构12和模板的结构的分析中找到。 但是基本概念对于所有类型都是通用的-包的内容由用符号分隔的段组成(在示例文本中,为便于阅读,每个段都显示在新行上)。 反过来,每个段可以包含任意数量的以*分隔的字段。

这样的协议使我们可以轻松地获得文档的线性结构,将其作为段列表及其字段列表。 但是,这还不足以恢复文档块的层次结构。 为此,正如我所提到的,应该使用一种方案,对于大多数类型的文档来说,这是一个相当大的文件。 但是,由于我们将不考虑文档验证的任务,而只限于解析,因此以下算法非常适合我们的目的-对于在文档段线性列表的顺序分析过程中遇到的每个段,我们需要获得唯一问题的答案:此段是否形成一个新的嵌套块,无论是当前块的结尾(同时是下一个块的开始),还是(在其他情况下)是当前块的内部段。

解析器


下面是Clojure代码,它将线性段结构解析为分层块结构。 为了定义层次结构,使用了一种声明性方法-最简单的循环数据结构,其中为列出的段分别指定了形成嵌套块并结束当前块的段列表。 当然,这种结构取决于文档的类型;实际上,它定义了其层次结构。 但是,下面的解析功能是通用的,并且当然可以在以这种方式正确设置的任何结构模板上使用,前提是所解析的文档的类型与所选模板匹配。

 ;; Parse 835 x12 string to hierarchical structure (def loops {"835" {:nested #{"ISA"}} "ISA" {:nested #{"GS"}} "GS" {:nested #{"ST"} :end #{"IEA"}} "ST" {:nested #{"N1" "LX"} :end #{"GE" "ST"}} "N1" {:end #{"SE" "LX" "N1"}} "LX" {:nested #{"CLP"} :end #{"SE" "LX"}} "CLP" {:nested #{"SVC"} :end #{"SE" "LX" "CLP"}} "SVC" {:end #{"SE" "LX" "CLP" "SVC"}}}) (defn parser-core [id ss acc] (let [seg-id (first (first ss)) {:keys [nested end]} (loops id)] (if (or (empty? ss) (and (contains? end seg-id) (not (empty? acc)))) [acc ss] (let [[v ss-] (if (contains? nested seg-id) (parser-core seg-id ss []) [(first ss) (rest ss)])] (recur id ss- (conj acc v)))))) (defn segments [s] (str/split (str/trim s) #"~")) (defn elements [s] (str/split (str/trim s) #"\*")) (defn x12 [s] (first (parser-core "835" (mapv elements (segments (or s ""))) []))) 


在扰流板下呈现

解析结果
 [[["ISA" "00" " " "00" " " "ZZ" "EMEDNYBAT " "ZZ" "ETIN " "140305" "0929" "^" "00501" "111111123" "0" "P" ":"] [["GS" "HP" "EMED" "ETIN" "20140301" "09304100" "111111123" "X" "005010X221A1"] [["ST" "835" "35681"] ["BPR" "I" "810.8" "C" "CHK" "" "" "" "" "" "" "" "" "" "" "" "20140331"] ["TRN" "1" "12345" "1512345678"] ["REF" "EV" "XYZ CLEARINGHOUSE"] [["N1" "PR" "DENTAL OF ABC"] ["N3" "225 MAIN STREET"] ["N4" "CENTERVILLE" "PA" "17111"] ["PER" "BL" "JANE DOE" "TE" "9005555555"]] [["N1" "PE" "BAN DDS LLC" "FI" "999994703"]] [["LX" "1"] [["CLP" "7722337" "1" "226" "132" "" "12" "119932404007801"] ["NM1" "QC" "1" "DOE" "SANDY" "" "" "" "MI" "SJD11112"] ["NM1" "82" "1" "BAN" "ERIN" "" "" "" "XX" "1811901945"] ["AMT" "AU" "132"] [["SVC" "AD:D0120" "46" "25"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "21"] ["AMT" "B6" "25"]] [["SVC" "AD:D0220" "25" "14"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "11"] ["AMT" "B6" "14"]] [["SVC" "AD:D0230" "22" "10"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "12"] ["AMT" "B6" "10"]] [["SVC" "AD:D0274" "60" "34"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "26"] ["AMT" "B6" "34"]] [["SVC" "AD:D1110" "73" "49"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "24"] ["AMT" "B6" "49"]]]] [["LX" "2"] [["CLP" "7722337" "1" "119" "74" "" "12" "119932404007801"] ["NM1" "QC" "1" "DOE" "SALLY" "" "" "" "MI" "SJD11111"] ["NM1" "IL" "1" "DOE" "JOHN" "" "" "" "MI" "123456"] ["NM1" "82" "1" "BAN" "ERIN" "" "" "" "XX" "1811901945"] ["AMT" "AU" "74"] [["SVC" "AD:D0120" "46" "25"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "21"] ["AMT" "B6" "25"]] [["SVC" "AD:D1110" "73" "49"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "24"] ["AMT" "B6" "49"]]]] [["LX" "3"] [["CLP" "7722337" "1" "226" "108" "24" "12" "119932404007801"] ["NM1" "QC" "1" "SMITH" "SALLY" "" "" "" "MI" "SJD11113"] ["NM1" "82" "1" "BAN" "ERIN" "" "" "" "XX" "1811901945"] ["AMT" "AU" "132"] [["SVC" "AD:D0120" "46" "25"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "21"] ["AMT" "B6" "25"]] [["SVC" "AD:D0220" "25" "0"] ["DTM" "472" "20140324"] ["CAS" "PR" "3" "14"] ["CAS" "CO" "131" "11"] ["AMT" "B6" "14"]] [["SVC" "AD:D0230" "22" "0"] ["DTM" "472" "20140324"] ["CAS" "PR" "3" "10"] ["CAS" "CO" "131" "12"] ["AMT" "B6" "10"]] [["SVC" "AD:D0274" "60" "34"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "26"] ["AMT" "B6" "34"]] [["SVC" "AD:D1110" "73" "49"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "24"] ["AMT" "B6" "49"]]]] [["LX" "4"] [["CLP" "7722337" "1" "1145" "14" "902" "12" "119932404007801"] ["NM1" "QC" "1" "SMITH" "SAM" "" "" "" "MI" "SJD11116"] ["NM1" "82" "1" "BAN" "ERIN" "" "" "" "XX" "1811901945"] ["AMT" "AU" "14"] [["SVC" "AD:D0220" "25" "14"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "11"] ["AMT" "B6" "14"]] [["SVC" "AD:D2790" "940" "0"] ["DTM" "472" "20140324"] ["CAS" "PR" "3" "756"] ["CAS" "CO" "131" "184"]] [["SVC" "AD:D2950" "180" "0"] ["DTM" "472" "20140324"] ["CAS" "PR" "3" "146"] ["CAS" "CO" "131" "34"]]]] [["LX" "5"] [["CLP" "7722337" "1" "348" "16.8" "44.2" "12" "119932404007801"] ["NM1" "QC" "1" "JONES" "SAM" "" "" "" "MI" "SJD11122"] ["NM1" "82" "1" "BAN" "ERIN" "" "" "" "XX" "1811901945"] ["AMT" "AU" "28"] [["SVC" "AD:D4342" "125" "0"] ["DTM" "472" "20140313"] ["CAS" "CO" "131" "125"]] [["SVC" "AD:D4381" "43" "0"] ["DTM" "472" "20140313"] ["CAS" "PR" "3" "33"] ["CAS" "CO" "131" "10"]] [["SVC" "AD:D2950" "180" "16.8"] ["DTM" "472" "20140313"] ["CAS" "PR" "3" "11.2"] ["CAS" "CO" "131" "152"] ["AMT" "B6" "28"]]]] [["LX" "6"] [["CLP" "7722337" "1" "226" "132" "" "12" "119932404007801"] ["NM1" "QC" "1" "JONES" "SALLY" "" "" "" "MI" "SJD11133"] ["NM1" "82" "1" "BAN" "ERIN" "" "" "" "XX" "1811901945"] ["AMT" "AU" "132"] [["SVC" "AD:D0120" "46" "25"] ["DTM" "472" "20140321"] ["CAS" "CO" "131" "21"] ["AMT" "B6" "25"]] [["SVC" "AD:D0220" "25" "14"] ["DTM" "472" "20140321"] ["CAS" "CO" "131" "11"] ["AMT" "B6" "14"]] [["SVC" "AD:D0230" "22" "10"] ["DTM" "472" "20140321"] ["CAS" "CO" "131" "12"] ["AMT" "B6" "10"]] [["SVC" "AD:D0274" "60" "34"] ["DTM" "472" "20140321"] ["CAS" "CO" "131" "26"] ["AMT" "B6" "34"]] [["SVC" "AD:D1110" "73" "49"] ["DTM" "472" "20140321"] ["CAS" "CO" "131" "24"] ["AMT" "B6" "49"]]]] [["LX" "7"] [["CLP" "7722337" "1" "179" "108" "" "12" "119932404007801"] ["NM1" "QC" "1" "DOE" "SAM" "" "" "" "MI" "SJD99999"] ["NM1" "82" "1" "BAN" "ERIN" "" "" "" "XX" "1811901945"] ["AMT" "AU" "108"] [["SVC" "AD:D0120" "46" "25"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "21"] ["AMT" "B6" "25"]] [["SVC" "AD:D0274" "60" "34"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "26"] ["AMT" "B6" "34"]] [["SVC" "AD:D1110" "73" "49"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "24"] ["AMT" "B6" "49"]]]] [["LX" "8"] [["CLP" "7722337" "1" "129" "82" "" "12" "119932404007801"] ["NM1" "QC" "1" "DOE" "SUE" "" "" "" "MI" "SJD88888"] ["NM1" "82" "1" "BAN" "ERIN" "" "" "" "XX" "1811901945"] ["AMT" "AU" "82"] [["SVC" "AD:D0120" "46" "25"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "21"] ["AMT" "B6" "25"]] [["SVC" "AD:D1120" "54" "37"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "17"] ["AMT" "B6" "37"]] [["SVC" "AD:D1208" "29" "20"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "9"] ["AMT" "B6" "20"]]]] [["LX" "9"] [["CLP" "7722337" "1" "221" "144" "" "12" "119932404007801"] ["NM1" "QC" "1" "DOE" "DONNA" "" "" "" "MI" "SJD77777"] ["NM1" "82" "1" "BAN" "ERIN" "" "" "" "XX" "1811901945"] ["AMT" "AU" "144"] [["SVC" "AD:D0120" "46" "25"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "21"] ["AMT" "B6" "25"]] [["SVC" "AD:D0330" "92" "62"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "30"] ["AMT" "B6" "62"]] [["SVC" "AD:D1120" "54" "37"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "17"] ["AMT" "B6" "37"]] [["SVC" "AD:D1208" "29" "20"] ["DTM" "472" "20140324"] ["CAS" "CO" "131" "9"] ["AMT" "B6" "20"]]]] ["SE" "190" "35681"]] ["GE" "1" "111111123"]] ["IEA" "1" "111111123"]]] 


我们最初的示例是段的层次结构。

实际上,已经可以考虑完成此任务。 十几行Clojure代码为我们提供了针对分层AST中任何X12文档的全功能解析器。 但是为了完整说明,您可以显示一个规避此AST来执行一些有用任务的示例-例如,构造所需格式的结构并将此信息写入数据库。 下面是一个代码示例,该代码绕过已解析的结构并基于该结构创建对象列表。 AST提供了一对通用辅助函数,可方便地访问数据,而树形遍历器可形成对象,并具有在层次结构的任何级别上访问原始数据的能力。

 ;; util helpers for extracting information (defn v-prefix? [vp] (and (vector? v) (= p (if (vector? p) (subvec v 0 (min (count v) (count p))) (get v 0))))) (defn items [vp & path] (filter #(v-prefix? (get-in % (vec path)) p) v)) (defn item [vp & path] (first (apply items vp path))) ;; test function for extracting human-readable structure (defn tst [x12-string] (for [isa (items (x12 x12-string) "ISA" 0) gs (items isa "GS" 0) st (items gs "ST" 0) lx (items st "LX" 0) clp (items lx "CLP" 0)] (let [bpr (item st "BPR")] {:message {:received (get-in isa [0 9]) :created (get-in gs [0 4])} :transaction {:check (get (item st "TRN") 2) :payed (get bpr 16) :total (read-string (get bpr 2))} :insurer (get-in (item st ["N1" "PR"] 0) [0 2]) :organization (get-in (item st ["N1" "PE"] 0) [0 2]) :claim {:patient (if-let [x (item clp ["NM1" "QC"])] (str (get x 3) " " (get x 4))) :total (read-string (get-in clp [0 4]))} :services (mapv (fn [svc] {:code (get-in svc [0 1]) :amount (read-string (get-in svc [0 3])) :date (get (item svc ["DTM" "472"]) 2)}) (items clp "SVC" 0))}))) 


在扰流板下呈现

功能结果
 ({:message {:received "140305", :created "20140301"}, :transaction {:check "12345", :payed "20140331", :total 810.8}, :insurer "DENTAL OF ABC", :organization "BAN DDS LLC", :claim {:patient "DOE SANDY", :total 132}, :services [{:code "AD:D0120", :amount 25, :date "20140324"} {:code "AD:D0220", :amount 14, :date "20140324"} {:code "AD:D0230", :amount 10, :date "20140324"} {:code "AD:D0274", :amount 34, :date "20140324"} {:code "AD:D1110", :amount 49, :date "20140324"}]} {:message {:received "140305", :created "20140301"}, :transaction {:check "12345", :payed "20140331", :total 810.8}, :insurer "DENTAL OF ABC", :organization "BAN DDS LLC", :claim {:patient "DOE SALLY", :total 74}, :services [{:code "AD:D0120", :amount 25, :date "20140324"} {:code "AD:D1110", :amount 49, :date "20140324"}]} {:message {:received "140305", :created "20140301"}, :transaction {:check "12345", :payed "20140331", :total 810.8}, :insurer "DENTAL OF ABC", :organization "BAN DDS LLC", :claim {:patient "SMITH SALLY", :total 108}, :services [{:code "AD:D0120", :amount 25, :date "20140324"} {:code "AD:D0220", :amount 0, :date "20140324"} {:code "AD:D0230", :amount 0, :date "20140324"} {:code "AD:D0274", :amount 34, :date "20140324"} {:code "AD:D1110", :amount 49, :date "20140324"}]} {:message {:received "140305", :created "20140301"}, :transaction {:check "12345", :payed "20140331", :total 810.8}, :insurer "DENTAL OF ABC", :organization "BAN DDS LLC", :claim {:patient "SMITH SAM", :total 14}, :services [{:code "AD:D0220", :amount 14, :date "20140324"} {:code "AD:D2790", :amount 0, :date "20140324"} {:code "AD:D2950", :amount 0, :date "20140324"}]} {:message {:received "140305", :created "20140301"}, :transaction {:check "12345", :payed "20140331", :total 810.8}, :insurer "DENTAL OF ABC", :organization "BAN DDS LLC", :claim {:patient "JONES SAM", :total 16.8}, :services [{:code "AD:D4342", :amount 0, :date "20140313"} {:code "AD:D4381", :amount 0, :date "20140313"} {:code "AD:D2950", :amount 16.8, :date "20140313"}]} {:message {:received "140305", :created "20140301"}, :transaction {:check "12345", :payed "20140331", :total 810.8}, :insurer "DENTAL OF ABC", :organization "BAN DDS LLC", :claim {:patient "JONES SALLY", :total 132}, :services [{:code "AD:D0120", :amount 25, :date "20140321"} {:code "AD:D0220", :amount 14, :date "20140321"} {:code "AD:D0230", :amount 10, :date "20140321"} {:code "AD:D0274", :amount 34, :date "20140321"} {:code "AD:D1110", :amount 49, :date "20140321"}]} {:message {:received "140305", :created "20140301"}, :transaction {:check "12345", :payed "20140331", :total 810.8}, :insurer "DENTAL OF ABC", :organization "BAN DDS LLC", :claim {:patient "DOE SAM", :total 108}, :services [{:code "AD:D0120", :amount 25, :date "20140324"} {:code "AD:D0274", :amount 34, :date "20140324"} {:code "AD:D1110", :amount 49, :date "20140324"}]} {:message {:received "140305", :created "20140301"}, :transaction {:check "12345", :payed "20140331", :total 810.8}, :insurer "DENTAL OF ABC", :organization "BAN DDS LLC", :claim {:patient "DOE SUE", :total 82}, :services [{:code "AD:D0120", :amount 25, :date "20140324"} {:code "AD:D1120", :amount 37, :date "20140324"} {:code "AD:D1208", :amount 20, :date "20140324"}]} {:message {:received "140305", :created "20140301"}, :transaction {:check "12345", :payed "20140331", :total 810.8}, :insurer "DENTAL OF ABC", :organization "BAN DDS LLC", :claim {:patient "DOE DONNA", :total 144}, :services [{:code "AD:D0120", :amount 25, :date "20140324"} {:code "AD:D0330", :amount 62, :date "20140324"} {:code "AD:D1120", :amount 37, :date "20140324"} {:code "AD:D1208", :amount 20, :date "20140324"}]}) 


-您可以投放到表格中以写入数据库,在UI上可视化或以任何其他方式使用

在我的工作项目中,使用了类似的代码和用于解析X12文档的算法-当然,还有很多其他功能。 本文中的代码示例是用于演示算法和方法的最小工作原型。 抱歉,没有抽象工厂,组合解析器,递归语法和其他重要内容-仅有三打代码行)

那些希望的人可以在支持Clojure的任何在线重播中使用此解析器-ideone / replit /etc。 在这些依赖项中,您只需要连接名称空间clojure.string ,也许还可以连接clojure.pprint以获得漂亮的结果。 您可以尝试更改创建对象的测试功能的代码,从已解析的结构中获取其他字段,等等。 可以在网上找到类型为835(索赔响应)的X12文档的示例。

Source: https://habr.com/ru/post/zh-CN427107/


All Articles