Menu

Cobol2Xml with REDEFINES

Help
2016-03-16
2016-03-20
  • Brian Reynolds

    Brian Reynolds - 2016-03-16

    Hi Bruce,

    We are creating a XML feed using a copybook that has redefines. This process is working fine, but further down-stream we are hitting XML parsing problems. This is because the record in question contains packed decimal values, and these come out in the base record as well as the redefined record. Simple example

    Data:

    89 84 99 3c 41 42 43 44 45 00 00 00 00 00
    

    Copybook:

            01 Base-Data PIC X(14).
            01 Data REDEFINES Base-Data.
                    02 Val1 PIC S9(7) COMP-3.
                    02 Val2 PIC X(10). 
    

    XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <CobolData>
        <Line>
            <Base-Data>���&lt;ABCDE     </Base-Data>
            <Data>
                <Val1>8984993</Val1>
                <Val2>ABCDE     </Val2>
            </Data>
        </Line>
    </CobolData>
    

    As you can see here, the XML "Base-Data" content has control characters, which cause our down-stream parsing to fail.

    Since we already have the correctly interpreted values displayed in the "Data" structure, is there any way to tell JRecord (at the Cobol2Xml level I guess) to not display "base data" if it's already been redefined?

    Thanks.

     
  • Bruce Martin

    Bruce Martin - 2016-03-17

    I probably advised against using the cobol-to-xml when there is a redefines for this very reason
    (If I did not, I meant to).

    That said, I should be able to Test redefined fields if they are valid. The one issue is the processing cost.

    I will do some testing and get back to you.

     
  • Brian Reynolds

    Brian Reynolds - 2016-03-17

    Thanks. I notice Cobol2GroupXml.cobol2xml is using the stock javax.xml.stream.XMLOutputFactory. If you extend the Cobol2Xml interface to set an XMLOutputFactory, you can then use something like the woodstox XMLOutputFactory - this allows an "InvalidCharHandler" to be defined, so it pushes the onus back on the caller to decide what to do when a NULL or something dodgy is encountered.

    E.g. code snippets:

    InvalidCharHandler charHandler = new InvalidCharHandler()
    {
        @Override
        public char convertInvalidChar(int arg0) throws IOException
        {
            if(arg0 == 0)
                return ' ';
            return (char)arg0;
            }
    };
    
    XMLOutputFactory wstxFactory = new WstxOutputFactory();
    ((WstxOutputFactory)wstxFactory).configureForSpeed();
    wstxFactory.setProperty(WstxOutputProperties.P_OUTPUT_INVALID_CHAR_HANDLER, charHandler);
    
    ICobol2Xml obj = Cobol2GroupXml.newCobol2Xml(is, "results")
                    .setFileOrganization(OptionsMapper.getFileOrganisation(this.organisation))
                    .setDialect(OptionsMapper.getDialect(this.dialect))
                    .setSplitCopybook(OptionsMapper.getSplit(this.copybookSplit))
                    .setFont(this.encoding)
                    .setStaxOutputFactory(wstxFactory) // <<
                ;
    

    Cobol2GroupXml

           public void cobol2xml(InputStream cobolStream, OutputStream xmlStream) throws IOException, JAXBException, XMLStreamException {
            doInit();
    
            AbstractLineReader r = iob.newReader(cobolStream);
            LayoutDetail schema =  iob.getLayout();
            AbstractLine l;
            XMLOutputFactory f ;
    
            if(this.outputFactory != null)
            {
                f = this.outputFactory;
            }
            else
            {
                f = XMLOutputFactory.newInstance();
            }
    
            XMLStreamWriter writer = f.createXMLStreamWriter(new OutputStreamWriter(xmlStream, STANDARD_FONT));
    

    I think it's quite an elegant solution,.

     

    Last edit: Brian Reynolds 2016-03-17
  • Bruce Martin

    Bruce Martin - 2016-03-17

    I will

    • Add the XMLOutputFactory factory option
    • I will also check (and remove) trailing ch=0x0000 from fields.
    • Will probably do an invalid check on Redefined fields (if there is a redefind comp/comp-3)
     
  • Bruce Martin

    Bruce Martin - 2016-03-20

    There is a new Download: https://sourceforge.net/projects/jrecord/files/jrecord/Version_0.80.8i/JRecord_Upgrade_20_Mar_2016.7z/download
    that holds these Changes

    • Can set the XMLInputFactory and XMOutputFactory
    • Trailing Low-Values (Hex-Zeros) are dropped from all fields
    • Redefined-Fields are now validated (When there is a redefined Comp*)

    The changes where applied to my "Updated-JRecord" which is very close another release
    So I suggest doing some Regression Tests. From a user perspective there should be few visible
    changes but there have been substantial internal changes:

    • IOBuilder / Cobol2Xml Interface Hierarchy has been changed. Also implementing classes
      have undergone substantial changes.
    • Csv-IOBuilders and Fixed-Width-IOBuilders have been fixed and Test cases written
    • Cobol2Csv classes have been rewritten with Csv-IOBulder and Cobol-IOBuilders.
      Fixes for Occurs-Depending have been made.

    For Cobol2Csv there are now tests for partially filled arrays; These tests are used
    in both Cobol ==> Xml and Xml ==> Cobol. Basically you can:

    • Check a whole array element for spaces / low-values / high-values before creating the Xml.
    • Set a array-size field
     

Log in to post a comment.