Skip to main content

Hello,

We need to generate Word documents from our Cobol application. I came across XMLDOCX which allows to create xml files and then convert them to docx document. The API is quite extended. 

I know that we can generate xml from Cobol. But I don't see how to generate cobol structures from the XML stuctures of the xmldocs api. For example, to add a text, here is the xml model :

<pdx:content>
    <pdx:addText pdx:wordFragmentName="">
        <pdx:textRun>
            <pdx:data pdx:dataId="" pdx:dataType="text|wordFragment">text</pdx:data>
            <pdx:textRunStyle>
                <pdx:bold pdx:value="" />
                <pdx:caps pdx:value="" />
                <pdx:color pdx:value="" />
                <pdx:doubleStrikeThrough pdx:value="" />
                <pdx:em pdx:value="" />
                <pdx:font pdx:value="" />
                <pdx:fontSize pdx:value="" />
                <pdx:highlightColor pdx:value="" />
                <pdx:italic pdx:value="" />
                <pdx:lang pdx:value="" />
                <pdx:lineBreak pdx:value="after|before|both" />
                <pdx:position pdx:value="" />
                <pdx:rStyle pdx:value="" />
                <pdx:rtl pdx:value="" />
                <pdx:scaling pdx:value="" />
                <pdx:smallCaps pdx:value="" />
                <pdx:spaces pdx:value="" />
                <pdx:spacing pdx:value="" />
                <pdx:strikeThrough pdx:value="" />
                <pdx:subscript pdx:value="" />
                <pdx:superscript pdx:value="" />
                <pdx:tab pdx:value="" />
                <pdx:underline pdx:value="" />
                <pdx:underlineColor pdx:value="" />
                <pdx:vanish pdx:value="" />
            </pdx:textRunStyle>
        </pdx:textRun>
        <pdx:textRun>
            <pdx:data pdx:dataId="" pdx:dataType="text|wordFragment">text</pdx:data>
            <pdx:textRunStyle>
                <pdx:bold pdx:value="" />
                <pdx:caps pdx:value="" />
                <pdx:color pdx:value="" />
                <pdx:columnBreak pdx:value="after|before|both" />
                <pdx:doubleStrikeThrough pdx:value="" />
                <pdx:em pdx:value="none|dot|circle|comma|underDot" />
                <pdx:font pdx:value="" />
                <pdx:fontSize pdx:value="" />
                <pdx:highlightColor pdx:value="" />
                <pdx:italic pdx:value="" />
                <pdx:lang pdx:value="" />
                <pdx:lineBreak pdx:value="after|before|both" />
                <pdx:rStyle pdx:value="" />
                <pdx:rtl pdx:value="" />
                <pdx:scaling pdx:value="" />
                <pdx:smallCaps pdx:value="" />
                <pdx:spaces pdx:value="" />
                <pdx:spacing pdx:value="" />
                <pdx:strikeThrough pdx:value="" />
                <pdx:subscript pdx:value="" />
                <pdx:superscript pdx:value="" />
                <pdx:tab pdx:value="" />
                <pdx:underline pdx:value="" />
                <pdx:underlineColor pdx:value="" />
                <pdx:vanish pdx:value="" />
            </pdx:textRunStyle>
        </pdx:textRun>
        <pdx:paragraphStyle>
            <pdx:backgroundColor pdx:value="" />
            <pdx:bidi pdx:value="" />
            <pdx:bold pdx:value="" />
            <pdx:border pdx:color="" pdx:space="" pdx:style="" pdx:width="">
                <pdx:top pdx:color="" pdx:space="" pdx:style="" pdx:width="" />
                <pdx:right pdx:color="" pdx:space="" pdx:style="" pdx:width="" />
                <pdx:bottom pdx:color="" pdx:space="" pdx:style="" pdx:width="" />
                <pdx:left pdx:color="" pdx:space="" pdx:style="" pdx:width="" />
            </pdx:border>
            <pdx:caps pdx:value="" />
            <pdx:color pdx:value="" />
            <pdx:contextualSpacing pdx:value="" />
            <pdx:doubleStrikeThrough pdx:value="" />
            <pdx:em pdx:value="none|dot|circle|comma|underDot" />
            <pdx:firstLineIndent pdx:value="" />
            <pdx:font pdx:value="" />
            <pdx:fontSize pdx:value="" />
            <pdx:hanging pdx:value="" />
            <pdx:headingLevel pdx:value="" />
            <pdx:italic pdx:value="" />
            <pdx:indentLeft pdx:value="" />
            <pdx:indentRight pdx:value="" />        
            <pdx:keepLines pdx:value="" />
            <pdx:keepNext pdx:value="" />
            <pdx:lineSpacing pdx:value="" />
            <pdx:pageBreakBefore pdx:value="" />
            <pdx:position pdx:value="" />
            <pdx:pStyle pdx:value="" />
            <pdx:rtl pdx:value="" />
            <pdx:smallCaps pdx:value="" />
            <pdx:spacing pdx:value="" />
            <pdx:spacingBottom pdx:value="" />
            <pdx:spacingTop pdx:value="" />
            <pdx:strikeThrough pdx:value="" />
            <pdx:tabPositions>
                <pdx:tabPosition pdx:type="" pdx:leader="" pdx:position="" />
                <pdx:tabPosition pdx:type="" pdx:leader="" pdx:position="" />
            </pdx:tabPositions>    
            <pdx:textAlign pdx:value="center|right|both|distribute" />
            <pdx:textDirection pdx:value="" />
            <pdx:underline pdx:value="" />
            <pdx:underlineColor pdx:value="" />
            <pdx:vanish pdx:value="" />
            <pdx:widowControl pdx:value="" />
            <pdx:wordWrap pdx:value="" />
        </pdx:paragraphStyle>
    </pdx:addText>
</pdx:content>

Or to add a list :

<pdx:content>
    <pdx:addList pdx:listType="" pdx:wordFragmentName="" pdx:useWordFragmentStyles="" pdx:pStyle="">
        <pdx:data pdx:dataId="" pdx:type="list">
            <pdx:item pdx:dataType pdx:depth="">item text</pdx:item>
            <pdx:item pdx:dataType pdx:depth="">item text</pdx:item>
            <pdx:item pdx:dataType pdx:depth="">item text</pdx:item>
        </pdx:data>
    </pdx:addList>
</pdx:content>

If we could create the schema to be used from cobol, it would then be possible to create Word documents directly from cobol.

Has someone any idea on how to create the cbl records from the above xml syntax ?

Regards,

Alain

Hello,

We need to generate Word documents from our Cobol application. I came across XMLDOCX which allows to create xml files and then convert them to docx document. The API is quite extended. 

I know that we can generate xml from Cobol. But I don't see how to generate cobol structures from the XML stuctures of the xmldocs api. For example, to add a text, here is the xml model :

<pdx:content>
    <pdx:addText pdx:wordFragmentName="">
        <pdx:textRun>
            <pdx:data pdx:dataId="" pdx:dataType="text|wordFragment">text</pdx:data>
            <pdx:textRunStyle>
                <pdx:bold pdx:value="" />
                <pdx:caps pdx:value="" />
                <pdx:color pdx:value="" />
                <pdx:doubleStrikeThrough pdx:value="" />
                <pdx:em pdx:value="" />
                <pdx:font pdx:value="" />
                <pdx:fontSize pdx:value="" />
                <pdx:highlightColor pdx:value="" />
                <pdx:italic pdx:value="" />
                <pdx:lang pdx:value="" />
                <pdx:lineBreak pdx:value="after|before|both" />
                <pdx:position pdx:value="" />
                <pdx:rStyle pdx:value="" />
                <pdx:rtl pdx:value="" />
                <pdx:scaling pdx:value="" />
                <pdx:smallCaps pdx:value="" />
                <pdx:spaces pdx:value="" />
                <pdx:spacing pdx:value="" />
                <pdx:strikeThrough pdx:value="" />
                <pdx:subscript pdx:value="" />
                <pdx:superscript pdx:value="" />
                <pdx:tab pdx:value="" />
                <pdx:underline pdx:value="" />
                <pdx:underlineColor pdx:value="" />
                <pdx:vanish pdx:value="" />
            </pdx:textRunStyle>
        </pdx:textRun>
        <pdx:textRun>
            <pdx:data pdx:dataId="" pdx:dataType="text|wordFragment">text</pdx:data>
            <pdx:textRunStyle>
                <pdx:bold pdx:value="" />
                <pdx:caps pdx:value="" />
                <pdx:color pdx:value="" />
                <pdx:columnBreak pdx:value="after|before|both" />
                <pdx:doubleStrikeThrough pdx:value="" />
                <pdx:em pdx:value="none|dot|circle|comma|underDot" />
                <pdx:font pdx:value="" />
                <pdx:fontSize pdx:value="" />
                <pdx:highlightColor pdx:value="" />
                <pdx:italic pdx:value="" />
                <pdx:lang pdx:value="" />
                <pdx:lineBreak pdx:value="after|before|both" />
                <pdx:rStyle pdx:value="" />
                <pdx:rtl pdx:value="" />
                <pdx:scaling pdx:value="" />
                <pdx:smallCaps pdx:value="" />
                <pdx:spaces pdx:value="" />
                <pdx:spacing pdx:value="" />
                <pdx:strikeThrough pdx:value="" />
                <pdx:subscript pdx:value="" />
                <pdx:superscript pdx:value="" />
                <pdx:tab pdx:value="" />
                <pdx:underline pdx:value="" />
                <pdx:underlineColor pdx:value="" />
                <pdx:vanish pdx:value="" />
            </pdx:textRunStyle>
        </pdx:textRun>
        <pdx:paragraphStyle>
            <pdx:backgroundColor pdx:value="" />
            <pdx:bidi pdx:value="" />
            <pdx:bold pdx:value="" />
            <pdx:border pdx:color="" pdx:space="" pdx:style="" pdx:width="">
                <pdx:top pdx:color="" pdx:space="" pdx:style="" pdx:width="" />
                <pdx:right pdx:color="" pdx:space="" pdx:style="" pdx:width="" />
                <pdx:bottom pdx:color="" pdx:space="" pdx:style="" pdx:width="" />
                <pdx:left pdx:color="" pdx:space="" pdx:style="" pdx:width="" />
            </pdx:border>
            <pdx:caps pdx:value="" />
            <pdx:color pdx:value="" />
            <pdx:contextualSpacing pdx:value="" />
            <pdx:doubleStrikeThrough pdx:value="" />
            <pdx:em pdx:value="none|dot|circle|comma|underDot" />
            <pdx:firstLineIndent pdx:value="" />
            <pdx:font pdx:value="" />
            <pdx:fontSize pdx:value="" />
            <pdx:hanging pdx:value="" />
            <pdx:headingLevel pdx:value="" />
            <pdx:italic pdx:value="" />
            <pdx:indentLeft pdx:value="" />
            <pdx:indentRight pdx:value="" />        
            <pdx:keepLines pdx:value="" />
            <pdx:keepNext pdx:value="" />
            <pdx:lineSpacing pdx:value="" />
            <pdx:pageBreakBefore pdx:value="" />
            <pdx:position pdx:value="" />
            <pdx:pStyle pdx:value="" />
            <pdx:rtl pdx:value="" />
            <pdx:smallCaps pdx:value="" />
            <pdx:spacing pdx:value="" />
            <pdx:spacingBottom pdx:value="" />
            <pdx:spacingTop pdx:value="" />
            <pdx:strikeThrough pdx:value="" />
            <pdx:tabPositions>
                <pdx:tabPosition pdx:type="" pdx:leader="" pdx:position="" />
                <pdx:tabPosition pdx:type="" pdx:leader="" pdx:position="" />
            </pdx:tabPositions>    
            <pdx:textAlign pdx:value="center|right|both|distribute" />
            <pdx:textDirection pdx:value="" />
            <pdx:underline pdx:value="" />
            <pdx:underlineColor pdx:value="" />
            <pdx:vanish pdx:value="" />
            <pdx:widowControl pdx:value="" />
            <pdx:wordWrap pdx:value="" />
        </pdx:paragraphStyle>
    </pdx:addText>
</pdx:content>

Or to add a list :

<pdx:content>
    <pdx:addList pdx:listType="" pdx:wordFragmentName="" pdx:useWordFragmentStyles="" pdx:pStyle="">
        <pdx:data pdx:dataId="" pdx:type="list">
            <pdx:item pdx:dataType pdx:depth="">item text</pdx:item>
            <pdx:item pdx:dataType pdx:depth="">item text</pdx:item>
            <pdx:item pdx:dataType pdx:depth="">item text</pdx:item>
        </pdx:data>
    </pdx:addList>
</pdx:content>

If we could create the schema to be used from cobol, it would then be possible to create Word documents directly from cobol.

Has someone any idea on how to create the cbl records from the above xml syntax ?

Regards,

Alain

It isn't clear to me what it is you wish to do here. If you wish to generate the XML enabled COBOL file records from an existing XML scema then you should take a look at the cbl2xml tool here:  

Are you using native COBOL or managed COBOL (.NET or JVM)?

It is possible to create a Word document directly from COBOL by using the COM Interop API to the Word COM server in native code or by using the Microsoft.Office.Interop.Word; class in a managed .NET COBOL program.

An example of this for native code is something like the following which is from the Net Express Example programs.

      *> This is required for OLE applications                         
      $set ooctrl(+P)                                                  
                                                                       
      **************************************************************** 
      * Copyright (C) 1997-1999 Micro Focus International Ltd.         
      * All Rights Reserved.                                           
      **************************************************************** 
      * The program demonstrates the use of OLE Automation to        * 
      * send messages to objects in another application. This        * 
      * example uses Microsoft Word.                                 * 
      *                                                              * 
      * It also demonstrates exception handling with regard to OLE   * 
      * objects, and the OLE support timeout method.                 * 
      *                                                              * 
      * The Word interface is documented in the file vbawrd8.hlp     * 
      * shipped with Microsoft Word 97 and vbawrd9.chm shipped       * 
      * with Microsoft Word 2000.                                    * 
      *                                                              * 
      * REQUIREMENTS: Microsoft Word 97 or above needs to be         * 
      * installed.                                                   * 
      *                                                              * 
      * $(#) V1.0                                                    * 
      **************************************************************** 
                                                                       
       program-id. worddemo.                                           
                                                                       
       class-control.                                                  
       *> Native Object COBOL classes                                  
           olesup is class "olesup"           *> OLE support class     
       *> OLE automation classes                                       
           wordapp is class "$OLE$word.application"                    
           .                                                           
                                                                       
       working-storage section.                                        
       01 wordServer       object reference value null.                
       01 theDocument      object reference value null.                
       01 theDocuments     object reference value null.                
       01 theSelection     object reference value null.                
       01 theFind          object reference value null.                
       01 theParagraph     object reference value null.                
       01 theParagraphs    object reference value null.                
       01 theRange         object reference value null.                
                                                                       
       01 found            pic s9(9) comp-5.                           
                                                                       
       procedure division.                                             
           *> Set the timeout for the OLE "busy" error to 100ms        
           *> Using this method is recommended for Word applications   
           invoke olesup "setOLEBusyTimeout" using by value 100        
                                                                       
           *> Create an instance of Word                               
           invoke wordapp "new" returning wordServer                   
                                                                       
           *> Make it visible                                          
           invoke wordServer "SetVisible" using by value 1             
                                                                       
           *> Get the Word documents collection object                 
           invoke wordServer "getDocuments" returning theDocuments     
                                                                       
           *> Create a new document. The Template and NewTemplate      
           *> parameters for this method are optional                  
           invoke theDocuments "add"                                   
                                                                       
           *> We no longer need the Documents collection               
           invoke theDocuments "finalize" returning theDocuments       
                                                                       
           *> Get the current selection                                
           invoke wordServer "getSelection" returning theSelection     
                                                                       
           *> Insert some lines of text in the new document            
           invoke theSelection "InsertAfter" using                     
                                      "This is a test line" & x"0d"    
           invoke theSelection "InsertAfter" using                     
                                     "This is the third line" & x"0d"  
                                                                       
           *> Finished with the selection object                       
           invoke theSelection "finalize" returning theSelection       
                                                                       
           *> Oops - we've put "third" instead of "second"             
           *> So, we'll replace that word. This is a bit convoluted,   
           *> but it's intended to give an idea of how collections work
                                                                       
           *> Get the active document                                  
           invoke wordServer "getActiveDocument" returning theDocument 
                                                                       
           *> Get the Paragraphs collection, then the second paragraph 
           *> using the item method, then the range of that paragraph; 
           *> Once we have the range, we've finished with paragraphs!  
           *> This does *exactly* the same as the VB command           
           *>   Range = Document.Paragraphs(2).Range                   
           invoke theDocument "getParagraphs" returning theParagraphs  
           invoke theParagraphs "item" using by value 2                
                               returning theParagraph                  
           invoke theParagraph "getRange" returning theRange           
           invoke theParagraph "finalize" returning theParagraph       
           invoke theParagraphs "finalize" returning theParagraphs     
                                                                       
           *> Get the Find object and ask it to find the text "third"  
           *> This should change theRange object's character range     
           invoke theRange "getFind" returning theFind                 
           invoke theFind "setForward" using by value 1                
           invoke theFind "setText" using by content z"third"          
           invoke theFind "execute"                                    
           invoke theFind "getFound" returning found                   
           invoke theFind "finalize" returning theFind                 
                                                                       
           if found not = 0                                            
               *> Select our new range of characters                   
               invoke theRange "select"                                
                                                                       
               *> Finally, change the word to the correct word!        
               invoke theRange "setText" using "second"                
           end-if                                                      
           invoke theRange "finalize" returning theRange               
                                                                       
           *> Print the document out                                   
           invoke theDocument "PrintOut" using by value 0              
                                                                       
           *> Close it without saving it                               
           invoke theDocument "Close" using by value 0                 
                                                                       
           *> We've finished with the document object                  
           invoke theDocument "finalize" returning theDocument         
                                                                       
           *> Tell Word to quit (it won't shut down otherwise)         
           invoke wordServer "quit"                                    
                                                                       
           *> We've now finished with the Word object                  
           invoke wordServer "finalize" returning wordServer           
                                                                       
           exit program                                                
           stop run.                                                   
                                                                       


It isn't clear to me what it is you wish to do here. If you wish to generate the XML enabled COBOL file records from an existing XML scema then you should take a look at the cbl2xml tool here:  

Are you using native COBOL or managed COBOL (.NET or JVM)?

It is possible to create a Word document directly from COBOL by using the COM Interop API to the Word COM server in native code or by using the Microsoft.Office.Interop.Word; class in a managed .NET COBOL program.

An example of this for native code is something like the following which is from the Net Express Example programs.

      *> This is required for OLE applications                         
      $set ooctrl(+P)                                                  
                                                                       
      **************************************************************** 
      * Copyright (C) 1997-1999 Micro Focus International Ltd.         
      * All Rights Reserved.                                           
      **************************************************************** 
      * The program demonstrates the use of OLE Automation to        * 
      * send messages to objects in another application. This        * 
      * example uses Microsoft Word.                                 * 
      *                                                              * 
      * It also demonstrates exception handling with regard to OLE   * 
      * objects, and the OLE support timeout method.                 * 
      *                                                              * 
      * The Word interface is documented in the file vbawrd8.hlp     * 
      * shipped with Microsoft Word 97 and vbawrd9.chm shipped       * 
      * with Microsoft Word 2000.                                    * 
      *                                                              * 
      * REQUIREMENTS: Microsoft Word 97 or above needs to be         * 
      * installed.                                                   * 
      *                                                              * 
      * $(#) V1.0                                                    * 
      **************************************************************** 
                                                                       
       program-id. worddemo.                                           
                                                                       
       class-control.                                                  
       *> Native Object COBOL classes                                  
           olesup is class "olesup"           *> OLE support class     
       *> OLE automation classes                                       
           wordapp is class "$OLE$word.application"                    
           .                                                           
                                                                       
       working-storage section.                                        
       01 wordServer       object reference value null.                
       01 theDocument      object reference value null.                
       01 theDocuments     object reference value null.                
       01 theSelection     object reference value null.                
       01 theFind          object reference value null.                
       01 theParagraph     object reference value null.                
       01 theParagraphs    object reference value null.                
       01 theRange         object reference value null.                
                                                                       
       01 found            pic s9(9) comp-5.                           
                                                                       
       procedure division.                                             
           *> Set the timeout for the OLE "busy" error to 100ms        
           *> Using this method is recommended for Word applications   
           invoke olesup "setOLEBusyTimeout" using by value 100        
                                                                       
           *> Create an instance of Word                               
           invoke wordapp "new" returning wordServer                   
                                                                       
           *> Make it visible                                          
           invoke wordServer "SetVisible" using by value 1             
                                                                       
           *> Get the Word documents collection object                 
           invoke wordServer "getDocuments" returning theDocuments     
                                                                       
           *> Create a new document. The Template and NewTemplate      
           *> parameters for this method are optional                  
           invoke theDocuments "add"                                   
                                                                       
           *> We no longer need the Documents collection               
           invoke theDocuments "finalize" returning theDocuments       
                                                                       
           *> Get the current selection                                
           invoke wordServer "getSelection" returning theSelection     
                                                                       
           *> Insert some lines of text in the new document            
           invoke theSelection "InsertAfter" using                     
                                      "This is a test line" & x"0d"    
           invoke theSelection "InsertAfter" using                     
                                     "This is the third line" & x"0d"  
                                                                       
           *> Finished with the selection object                       
           invoke theSelection "finalize" returning theSelection       
                                                                       
           *> Oops - we've put "third" instead of "second"             
           *> So, we'll replace that word. This is a bit convoluted,   
           *> but it's intended to give an idea of how collections work
                                                                       
           *> Get the active document                                  
           invoke wordServer "getActiveDocument" returning theDocument 
                                                                       
           *> Get the Paragraphs collection, then the second paragraph 
           *> using the item method, then the range of that paragraph; 
           *> Once we have the range, we've finished with paragraphs!  
           *> This does *exactly* the same as the VB command           
           *>   Range = Document.Paragraphs(2).Range                   
           invoke theDocument "getParagraphs" returning theParagraphs  
           invoke theParagraphs "item" using by value 2                
                               returning theParagraph                  
           invoke theParagraph "getRange" returning theRange           
           invoke theParagraph "finalize" returning theParagraph       
           invoke theParagraphs "finalize" returning theParagraphs     
                                                                       
           *> Get the Find object and ask it to find the text "third"  
           *> This should change theRange object's character range     
           invoke theRange "getFind" returning theFind                 
           invoke theFind "setForward" using by value 1                
           invoke theFind "setText" using by content z"third"          
           invoke theFind "execute"                                    
           invoke theFind "getFound" returning found                   
           invoke theFind "finalize" returning theFind                 
                                                                       
           if found not = 0                                            
               *> Select our new range of characters                   
               invoke theRange "select"                                
                                                                       
               *> Finally, change the word to the correct word!        
               invoke theRange "setText" using "second"                
           end-if                                                      
           invoke theRange "finalize" returning theRange               
                                                                       
           *> Print the document out                                   
           invoke theDocument "PrintOut" using by value 0              
                                                                       
           *> Close it without saving it                               
           invoke theDocument "Close" using by value 0                 
                                                                       
           *> We've finished with the document object                  
           invoke theDocument "finalize" returning theDocument         
                                                                       
           *> Tell Word to quit (it won't shut down otherwise)         
           invoke wordServer "quit"                                    
                                                                       
           *> We've now finished with the Word object                  
           invoke wordServer "finalize" returning wordServer           
                                                                       
           exit program                                                
           stop run.                                                   
                                                                       

Thank you, dear Chris, for as always a prompt answer!

I was not precise enough : we use native Cobol under Centos.

My idea was to generate the xml files using the write statement. But I do not sse how to create a match between the XD file description and the xml structures as proposed in xmldocx. It seems a little bit different.

But if it is possible, then creating docx files from native cobol becomes "easy".

Regards

Alain


Hello,

We need to generate Word documents from our Cobol application. I came across XMLDOCX which allows to create xml files and then convert them to docx document. The API is quite extended. 

I know that we can generate xml from Cobol. But I don't see how to generate cobol structures from the XML stuctures of the xmldocs api. For example, to add a text, here is the xml model :

<pdx:content>
    <pdx:addText pdx:wordFragmentName="">
        <pdx:textRun>
            <pdx:data pdx:dataId="" pdx:dataType="text|wordFragment">text</pdx:data>
            <pdx:textRunStyle>
                <pdx:bold pdx:value="" />
                <pdx:caps pdx:value="" />
                <pdx:color pdx:value="" />
                <pdx:doubleStrikeThrough pdx:value="" />
                <pdx:em pdx:value="" />
                <pdx:font pdx:value="" />
                <pdx:fontSize pdx:value="" />
                <pdx:highlightColor pdx:value="" />
                <pdx:italic pdx:value="" />
                <pdx:lang pdx:value="" />
                <pdx:lineBreak pdx:value="after|before|both" />
                <pdx:position pdx:value="" />
                <pdx:rStyle pdx:value="" />
                <pdx:rtl pdx:value="" />
                <pdx:scaling pdx:value="" />
                <pdx:smallCaps pdx:value="" />
                <pdx:spaces pdx:value="" />
                <pdx:spacing pdx:value="" />
                <pdx:strikeThrough pdx:value="" />
                <pdx:subscript pdx:value="" />
                <pdx:superscript pdx:value="" />
                <pdx:tab pdx:value="" />
                <pdx:underline pdx:value="" />
                <pdx:underlineColor pdx:value="" />
                <pdx:vanish pdx:value="" />
            </pdx:textRunStyle>
        </pdx:textRun>
        <pdx:textRun>
            <pdx:data pdx:dataId="" pdx:dataType="text|wordFragment">text</pdx:data>
            <pdx:textRunStyle>
                <pdx:bold pdx:value="" />
                <pdx:caps pdx:value="" />
                <pdx:color pdx:value="" />
                <pdx:columnBreak pdx:value="after|before|both" />
                <pdx:doubleStrikeThrough pdx:value="" />
                <pdx:em pdx:value="none|dot|circle|comma|underDot" />
                <pdx:font pdx:value="" />
                <pdx:fontSize pdx:value="" />
                <pdx:highlightColor pdx:value="" />
                <pdx:italic pdx:value="" />
                <pdx:lang pdx:value="" />
                <pdx:lineBreak pdx:value="after|before|both" />
                <pdx:rStyle pdx:value="" />
                <pdx:rtl pdx:value="" />
                <pdx:scaling pdx:value="" />
                <pdx:smallCaps pdx:value="" />
                <pdx:spaces pdx:value="" />
                <pdx:spacing pdx:value="" />
                <pdx:strikeThrough pdx:value="" />
                <pdx:subscript pdx:value="" />
                <pdx:superscript pdx:value="" />
                <pdx:tab pdx:value="" />
                <pdx:underline pdx:value="" />
                <pdx:underlineColor pdx:value="" />
                <pdx:vanish pdx:value="" />
            </pdx:textRunStyle>
        </pdx:textRun>
        <pdx:paragraphStyle>
            <pdx:backgroundColor pdx:value="" />
            <pdx:bidi pdx:value="" />
            <pdx:bold pdx:value="" />
            <pdx:border pdx:color="" pdx:space="" pdx:style="" pdx:width="">
                <pdx:top pdx:color="" pdx:space="" pdx:style="" pdx:width="" />
                <pdx:right pdx:color="" pdx:space="" pdx:style="" pdx:width="" />
                <pdx:bottom pdx:color="" pdx:space="" pdx:style="" pdx:width="" />
                <pdx:left pdx:color="" pdx:space="" pdx:style="" pdx:width="" />
            </pdx:border>
            <pdx:caps pdx:value="" />
            <pdx:color pdx:value="" />
            <pdx:contextualSpacing pdx:value="" />
            <pdx:doubleStrikeThrough pdx:value="" />
            <pdx:em pdx:value="none|dot|circle|comma|underDot" />
            <pdx:firstLineIndent pdx:value="" />
            <pdx:font pdx:value="" />
            <pdx:fontSize pdx:value="" />
            <pdx:hanging pdx:value="" />
            <pdx:headingLevel pdx:value="" />
            <pdx:italic pdx:value="" />
            <pdx:indentLeft pdx:value="" />
            <pdx:indentRight pdx:value="" />        
            <pdx:keepLines pdx:value="" />
            <pdx:keepNext pdx:value="" />
            <pdx:lineSpacing pdx:value="" />
            <pdx:pageBreakBefore pdx:value="" />
            <pdx:position pdx:value="" />
            <pdx:pStyle pdx:value="" />
            <pdx:rtl pdx:value="" />
            <pdx:smallCaps pdx:value="" />
            <pdx:spacing pdx:value="" />
            <pdx:spacingBottom pdx:value="" />
            <pdx:spacingTop pdx:value="" />
            <pdx:strikeThrough pdx:value="" />
            <pdx:tabPositions>
                <pdx:tabPosition pdx:type="" pdx:leader="" pdx:position="" />
                <pdx:tabPosition pdx:type="" pdx:leader="" pdx:position="" />
            </pdx:tabPositions>    
            <pdx:textAlign pdx:value="center|right|both|distribute" />
            <pdx:textDirection pdx:value="" />
            <pdx:underline pdx:value="" />
            <pdx:underlineColor pdx:value="" />
            <pdx:vanish pdx:value="" />
            <pdx:widowControl pdx:value="" />
            <pdx:wordWrap pdx:value="" />
        </pdx:paragraphStyle>
    </pdx:addText>
</pdx:content>

Or to add a list :

<pdx:content>
    <pdx:addList pdx:listType="" pdx:wordFragmentName="" pdx:useWordFragmentStyles="" pdx:pStyle="">
        <pdx:data pdx:dataId="" pdx:type="list">
            <pdx:item pdx:dataType pdx:depth="">item text</pdx:item>
            <pdx:item pdx:dataType pdx:depth="">item text</pdx:item>
            <pdx:item pdx:dataType pdx:depth="">item text</pdx:item>
        </pdx:data>
    </pdx:addList>
</pdx:content>

If we could create the schema to be used from cobol, it would then be possible to create Word documents directly from cobol.

Has someone any idea on how to create the cbl records from the above xml syntax ?

Regards,

Alain

I am back with the XML.

I have the following xsd file (an extraction from a bigger one)

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.phpdocx.com/main" xmlns:pdx="http://www.phpdocx.com/main">
  <xs:element name="document">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="pdx:config"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="config">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="pdx:template"/>
        <xs:element ref="pdx:output"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="template">
    <xs:complexType>
      <xs:attribute name="path" use="required" form="qualified"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="output">
    <xs:complexType>
      <xs:attribute name="name" use="required" form="qualified"/>
      <xs:attribute name="type" use="required" form="qualified" type="xs:NCName"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

When I create the cpy file from this xsd using cbl2xml xmldocx2.xsd  there are no errors but warnings :

Warning : Unable to convert schema element "path" to COBOL (empty structure)
Warning : Unable to convert schema element "name" to COBOL (empty structure)
Warning : Unable to convert schema element "path" to COBOL (empty structure)
Warning : Unable to convert schema element "name" to COBOL (empty structure)
Warning : Unable to convert schema element "path" to COBOL (empty structure)
Warning : Unable to convert schema element "name" to COBOL (empty structure)
Warning : Unable to convert schema element "name" to COBOL (empty structure)

Successfully converted 1 of 1 schema head element(s).

0 error(s), 8 warning(s)

and the cpy files looks like this :

       01 document identified by "document" namespace is "http://www.phpdocx.com/main" count in document-count.
        02 config identified by "config" count in config-count.
         03 output identified by "output" count in output-count.
          04 type PIC X(80) identified by "type" is attribute count in type-count.

Instead of something like that

       01 document identified by "pdx:document" namespace is "http://www.phpdocx.com/main" count in document-count.
        02 config identified by "pdx:config" count in config-count.
         03 Template identified by "pdx:template" count in template-count.
          04 aPath PIC X(80) identified by "pdx:path" is attribute count in type-count.
         03 anOutput identified by "pdx:output" count in output-count.
          04 aName PIC X(80) identified by "pdx:name" is attribute count in aname-count.
          04 aType PIC X(80) identified by "pdx:type" is attribute count in atype-count.

The xml generated should look like this :

<?xml version="1.0" encoding="UTF-8"?>
<pdx:document xmlns:pdx="http://www.phpdocx.com/main" >
    <pdx:config>
        <pdx:template pdx:path="/Mypathto/empty.docx" />
        <pdx:output pdx:name="output" pdx:type="docx" />
    </pdx:config>
</pdx:document>

Which is impossible with the cpy file created directly from cbl2xml.

A lot of attributes where not created. Is it a limitation of cbl2xml ? Or a problem with the xsd file although it passes the validation with cbl2xml ?

The full xsd is quite long, so doing it by hand is very fastidious!

Regards,

Alain


I am back with the XML.

I have the following xsd file (an extraction from a bigger one)

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.phpdocx.com/main" xmlns:pdx="http://www.phpdocx.com/main">
  <xs:element name="document">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="pdx:config"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="config">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="pdx:template"/>
        <xs:element ref="pdx:output"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="template">
    <xs:complexType>
      <xs:attribute name="path" use="required" form="qualified"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="output">
    <xs:complexType>
      <xs:attribute name="name" use="required" form="qualified"/>
      <xs:attribute name="type" use="required" form="qualified" type="xs:NCName"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

When I create the cpy file from this xsd using cbl2xml xmldocx2.xsd  there are no errors but warnings :

Warning : Unable to convert schema element "path" to COBOL (empty structure)
Warning : Unable to convert schema element "name" to COBOL (empty structure)
Warning : Unable to convert schema element "path" to COBOL (empty structure)
Warning : Unable to convert schema element "name" to COBOL (empty structure)
Warning : Unable to convert schema element "path" to COBOL (empty structure)
Warning : Unable to convert schema element "name" to COBOL (empty structure)
Warning : Unable to convert schema element "name" to COBOL (empty structure)

Successfully converted 1 of 1 schema head element(s).

0 error(s), 8 warning(s)

and the cpy files looks like this :

       01 document identified by "document" namespace is "http://www.phpdocx.com/main" count in document-count.
        02 config identified by "config" count in config-count.
         03 output identified by "output" count in output-count.
          04 type PIC X(80) identified by "type" is attribute count in type-count.

Instead of something like that

       01 document identified by "pdx:document" namespace is "http://www.phpdocx.com/main" count in document-count.
        02 config identified by "pdx:config" count in config-count.
         03 Template identified by "pdx:template" count in template-count.
          04 aPath PIC X(80) identified by "pdx:path" is attribute count in type-count.
         03 anOutput identified by "pdx:output" count in output-count.
          04 aName PIC X(80) identified by "pdx:name" is attribute count in aname-count.
          04 aType PIC X(80) identified by "pdx:type" is attribute count in atype-count.

The xml generated should look like this :

<?xml version="1.0" encoding="UTF-8"?>
<pdx:document xmlns:pdx="http://www.phpdocx.com/main" >
    <pdx:config>
        <pdx:template pdx:path="/Mypathto/empty.docx" />
        <pdx:output pdx:name="output" pdx:type="docx" />
    </pdx:config>
</pdx:document>

Which is impossible with the cpy file created directly from cbl2xml.

A lot of attributes where not created. Is it a limitation of cbl2xml ? Or a problem with the xsd file although it passes the validation with cbl2xml ?

The full xsd is quite long, so doing it by hand is very fastidious!

Regards,

Alain

I think one of the problems is that the schema file attributes do not have types associated with them so there is no COBOL data-name and PIC clause that can be generated.

For example if I add in the type="xs:string" to the attricbute lines then the resultant .cpy will look closer to what you show above...I am still investigating the namespace issue but I believe it may be a limitation.


I think one of the problems is that the schema file attributes do not have types associated with them so there is no COBOL data-name and PIC clause that can be generated.

For example if I add in the type="xs:string" to the attricbute lines then the resultant .cpy will look closer to what you show above...I am still investigating the namespace issue but I believe it may be a limitation.

It looks like you will have to make some modifications to the schema and to the generated copybook.

I can get the desired results with the following program:

$set preprocess(prexml) endp
       identification division.
       program-id. Program1.

            select xml-file assign to "xmlout.xml"
                            organization is xml
                            file status is xml-status.
       data division.
       
       file section.
       xd xml-file.
       01 document identified by "pdx:document" namespace is 
          "http://www.phpdocx.com/main" count in document-count.
        02 config identified by "pdx:config" count in config-count.
         03 template identified by "pdx:template" count in
         template-count.
          04 path PIC X(80) identified by "path" is attribute
            count in path-count.
         03 aoutput identified by "pdx:output" count in output-count.
          04 aname PIC X(80) identified by "name" is attribute count in 
             name-count.
          04 atype PIC X(80) identified by "type" is attribute count in 
             type-count.
       working-storage section.
       01 xml-status  pic s9(9).

       procedure division.

           open output xml-file
           write document key is plain-text '<?xml version="1.0" encoding="UTF-8"?>'
           move "/Mypathto/empty.docx" to path
           move "output" to aname
           move "docx" to atype
           write document
           close xml-file
           goback.


It looks like you will have to make some modifications to the schema and to the generated copybook.

I can get the desired results with the following program:

$set preprocess(prexml) endp
       identification division.
       program-id. Program1.

            select xml-file assign to "xmlout.xml"
                            organization is xml
                            file status is xml-status.
       data division.
       
       file section.
       xd xml-file.
       01 document identified by "pdx:document" namespace is 
          "http://www.phpdocx.com/main" count in document-count.
        02 config identified by "pdx:config" count in config-count.
         03 template identified by "pdx:template" count in
         template-count.
          04 path PIC X(80) identified by "path" is attribute
            count in path-count.
         03 aoutput identified by "pdx:output" count in output-count.
          04 aname PIC X(80) identified by "name" is attribute count in 
             name-count.
          04 atype PIC X(80) identified by "type" is attribute count in 
             type-count.
       working-storage section.
       01 xml-status  pic s9(9).

       procedure division.

           open output xml-file
           write document key is plain-text '<?xml version="1.0" encoding="UTF-8"?>'
           move "/Mypathto/empty.docx" to path
           move "output" to aname
           move "docx" to atype
           write document
           close xml-file
           goback.

Thank you!