Parsim X12 "على الركبة"

الصورة عند إنشاء تطبيق يتفاعل بنشاط مع خدمات وأنظمة الطرف الثالث ، غالبًا ما يُطلب منه توفير تبادل المعلومات معهم ، في اتجاه واحد أو ثنائي الاتجاه

ومع ذلك ، غالبًا ما توفر خدمة الطرف الثالث تنسيقًا واحدًا وهيكل بيانات لهذا التفاعل.

أحد تنسيقات إدارة المستندات الإلكترونية هو EDI ANSI ASC X12 ، ويرد وصف تفصيلي إلى حد ما هنا.

تم أخذ KDPV من هذا الموقع


يوجد تحت القطة خوارزمية محلل X12 بسيطة ورمز Clojure يقوم بتنفيذ المحلل اللغوي ومثال على معالجة البيانات المحللة.

قليلا عن التنسيق


نقلاً عن الرابط أعلاه:
تم تطوير معيار تبادل الوثائق الإلكترونية ANSI ASC X12 (لجنة المعايير المعتمدة من قبل معهد المعايير الأمريكية X12) في السبعينيات عندما كان الحجم الصغير للمستند الإلكتروني مهمًا (لأجهزة المودم بسرعات 300-1200 بت في الثانية) وكان على كل بايت أن يحمل أقصى قدر من المعلومات. وهكذا ، تم التخلي عن "سهولة قراءة" الوثيقة الإلكترونية لصالح "كثافة المعلومات".

لذلك ، لن ترى أي جمال يمكن قراءته في الإنسان ، كما هو الحال في XML. وعلى الرغم من أن المعيار يسمح لك بإنشاء مستندات ذات هيكل هرمي معقد إلى حد ما ، مع وجود كتل وما يسمى بالحلقات ، ومع ذلك ، لا يتم توفير حتى علامات الإغلاق لجميع الكتل (باستثناء ISA / GS / ST). من خلال رابط الكاتا ، يمكن للجميع التعرف على هيكل ووصف التنسيق بالتفصيل ، ثم سنتناول فقط الأشياء الضرورية.

يحتوي كل نوع من المستندات على هيكل قالب خاص به ، يشير إلى معنى وغرض الحقول والمقاطع الفردية ، وأنواعها وقيمها المحتملة ، بالإضافة إلى قائمة بالمقاطع والكتل المطلوبة والاختيارية. إصدار القوالب مدعوم ؛ يتم إرسال المعلومات حول النوع ورقم الإصدار في الحقول المقابلة من المستند. من المفترض أنه يستخدم قالبًا لنوع معين من المستندات يجب تحليله والتحقق من صحته.

فيما يلي مثال على مستند يحتوي على العديد من المعاملات من النوع 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 بمحلل كامل الوظائف لأية مستندات X12 في AST الهرمي. ولكن لإكمال الصورة ، يمكنك إظهار مثال للتحايل على 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"}]}) 


- يمكنك أن تخدم على الطاولة للكتابة إلى قاعدة البيانات ، أو تصور على واجهة المستخدم أو استخدامها بأي طريقة أخرى

يتم استخدام رمز مشابه وخوارزمية لتحليل مستندات X12 في مشروع عملي - بالطبع ، مع مجموعة من الوظائف الإضافية. أمثلة التعليمات البرمجية في المقالة هي نموذج أولي يعمل بالحد الأدنى لإثبات الخوارزمية والنهج. عذرًا ، بدون مصانع مجردة ، ومحللات مجمعة ، وقواعد تعاودية وأشياء خطيرة أخرى - لا يوجد سوى ثلاث عشرة سطرًا من التعليمات البرمجية)

أولئك الذين يرغبون في اللعب مع هذا المحلل اللغوي في أي إعادة تشغيل عبر الإنترنت تدعم Clojure - ideone / replit / etc. من التبعيات ، تحتاج فقط إلى ربط مساحة الاسم clojure.string ، حسنًا ، ربما clojure.pprint للحصول على طباعة جميلة للنتائج. يمكنك محاولة تغيير كود وظيفة الاختبار لإنشاء الكائن ، والحصول على حقول أخرى من الهيكل المعرب ، إلخ. يمكن العثور على أمثلة لمستندات X12 من النوع 835 (الرد على المطالبة) عبر الإنترنت.

Source: https://habr.com/ru/post/ar427107/


All Articles