How to eliminate Junk values while doing XML generate in COBOL

109 views Asked by At

I have a COBOL-DB2 code where it fetches the data from DB2 and moves the value to a copybook variable (XML structure). While doing XML Generate, the code fails with XML-CODE=000000417. This is because the DB2 value has a junk value. Now, I am trying to find the answers for below question. Hope someone can help

  1. How to eliminate junk characters while doing XML Generate ? Is there any function ?

    Note: Inspect/perform on the variable might be difficult before XML generate as there are multiple group variables to be XML generated. Also, for Inspect we need to know the list of Junk values.

  2. Is there any possibility to get the list of Junk values ? Might sound silly

Any good solutions to the above issue will be very helpful. Thanks

DATA in DB2 - Ralphs Basketball Team. You can see a junk character between h and s in Ralph_s. The Hex value of Junk is x'3F'

Code:

Fetches the data from DB2 and then,

     MOVE NAME               TO Name1         
                             IN Output  
                                              
     MOVE ADDRESS1           TO ADDRESS       
                             IN Output

     MOVE SPACES             TO WS-XML-OUTPUT


    XML GENERATE WS-XML-OUTPUT FROM Output   
                         COUNT IN WS-NUMS
           SUPPRESS EVERY nonnumeric element WHEN SPACE     
                    EVERY nonnumeric element WHEN LOW-VALUES

       ON EXCEPTION
          SET ERROR                      IN WS-ACTION 
          MOVE XML-CODE                  TO WS-XML-CODE
          STRING 'XML GENERATE ERROR AT POSITION=' 
                                         WS-NUMS      
                 ', XML-CODE=' WS-XML-CODE         
                 ', XML=' WS-XML-OUTPUT(1:100) 
          INTO WS-ERROR-TEXT  

       NOT ON EXCEPTION
           MOVE WS-XML-OUTPUT       TO WS-REC
           .
           .
   END-XML

Note: I cannot use the below code to replace the junk with space after the DB2 fetch. This is because there are multiple group variables which needs to be XML generated and cannot use on every group variable. This might affect the performance.

Perform IX1 from 1 by 1 until IX1 > 100
  IF NAME(IX1:1) < SPACE
     Move space to NAME(IX1:1)
  END-IF
END-PERFORM

Looking for a better solution and a generic one.

1

There are 1 answers

0
cschneid On

I'm going to expand a bit on the comment by @Gilbert-Le-Blanc, but please don't take this as me putting words in his mouth. There is no simple answer to your question.

You cannot do this generically. The reason you cannot do this generically is that "junk values" is context-dependent. What is "junk" in one field may not be junk in another field. What is considered to be "junk" for the purposes of your program may be required by another program processing the same column in the same DB2 table. COBOL doesn't know what you consider to be "junk values," but see below.

As an example, your program is generating XML, and the XML GENERATE has a problem with character x'3F'. Another program may be detecting the x'3F' and replacing it with x'7D' (an apostrophe).

If you can determine that all programs using a given column consider the same individual character values to be "junk values," then you could request a BEFORE INSERT OR UPDATE trigger be placed on that column, where the trigger would signal an error (or modify the data being used for INSERT or UPDATE) if the "junk values" were present, then the "junk values" would never enter the DB2 table. Note that this would probably involve processing the incoming data character-by-character. This would also involve reprocessing the existing contents of the table to ensure it conforms to the new "junk values" trigger.

Your concern about the performance of processing each field character-by-character in your program is noted, but any process by which "junk values" are replaced in your code is going to happen character-by-character whether explicitly in your code or "behind the scenes" in the code generated by the compiler or in a runtime routine.

You may be able to offset your performance concerns via multi-row fetch, which is a whole separate topic.

If your shop is not willing prevent "junk values" entering the system, then you must process each field character-by-character to replace values which offend the XML GENERATE process with values which do not. One way to do that would be...

*    Untested, freehand, not guaranteed to compile or work at all
 Working-Storage Section.
 01  WS-CONVERT-JUNK.
     05  WS-CONVERT-FROM PIC X(256) VALUE
                                  X'000102030405060708090A0B0C0D0E0F
-                                  '101112131415161718191A1B1C1D1E1F
-                                  '202122232425262728292A2B2C2D2E2F
-                                  '303132333435363738393A3B3C3D3E3F
-                                  '404142434445464748494A4B4C4D4E4F
-                                  '505152535455565758595A5B5C5D5E5F
-                                  '606162636465666768696A6B6C6D6E6F
-                                  '707172737475767778797A7B7C7D7E7F
-                                  '808182838485868788898A8B8C8D8E8F
-                                  '909192939495969798999A9B9C9D9E9F
-                                  'A0A1A2A3A4A5A6A7A8A9AAABACADAEAF
-                                  'B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF
-                                  'C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF
-                                  'D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF
-                                  'E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
-                                'F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF'.
*        Code page 37
     05  WS-CONVERT-TO   PIC X(256) VALUE
                                  X'40404040404040404040404040404040
-                                  '40404040404040404040404040404040
-                                  '40404040404040404040404040404040
-                                  '40404040404040404040404040404040
-                                  '40404040404040404040404B4C4D4E40
-                                  '504040404040404040405A5B5C5D5E40
-                                  '60614040404040404040406B6C6D6E6F
-                                  '404040404040404040407A7B7C7D7E7F
-                                  '40404040404040404040404040404040
-                                  '40818283848586878889404040404040
-                                  '40919293949596979899404040404040
-                                  '4040A2A3A4A5A6A7A8A9404040404040
-                                  '40404040404040404040404040404040
-                                  '40C1C2C3C4C5C6C7C8C9404040404040
-                                  '40D1D2D3D4D5D6D7D8D9404040404040
-                                  '4040E2E3E4E5E6E7E8E9404040404040
-                                'F0F1F2F3F4F5F6F7F8F9404040404040'.

...where you code x'40' for each "junk value" you wish replaced by a space and the same corresponding hex value for each that you do not. You must be conscious of the code page you are working with and keep in mind the code page of your DB2 table may be different from the code page of your COBOL program. Then, for each Working-Storage identifier in your program which contains character data FETCHed from your DB2 table you can code...

    INSPECT field CONVERTING WS-CONVERT-FROM TO WS-CONVERT-FROM

...and your XML GENERATE will not complain of invalid values.