COBOL 中的 XML,具有嵌套表和不同的子项

发布于 2024-08-18 12:45:27 字数 666 浏览 2 评论 0原文

是否可以使用 XML GENERATE 创建具有不同大小的多层嵌套元素的 XML?

例如:

01  SOURCE-REC.
    05  REPEATING-PARENT OCCURS 5 TIMES.
        10  PARENT-NAME PIC X(7).
        10  CHILD-COUNT PIC 9.
        10  REPEATING-CHILD OCCURS 1 TO 5 TIMES
                DEPENDING ON CHILD-COUNT.
            15  CHILD-NAME PIC X(6).

使用 Enterprise Cobol v4.1 编译此结果:

IGYGR1263-S“OCCURS DEPENDING ON”对象“CHILD-COUNT”被定义为表 元素。 “取决于”短语被丢弃。

IGYGR1116-S 表“REPEATING-CHILD”的“DEPENDING ON”对象无效。这 “取决于”短语被丢弃。

并非所有父母都会拥有相同数量的孩子。如何解决这个问题?

编辑:我想从本质上讲,这并不是一个真正的 XML 问题。我在试图构建工作存储时遇到了困难,我后来希望将其输入到 XML GENERATE 中。

Is it possible to use XML GENERATE to create XML with multi-level nested elements of different sizes?

For example:

01  SOURCE-REC.
    05  REPEATING-PARENT OCCURS 5 TIMES.
        10  PARENT-NAME PIC X(7).
        10  CHILD-COUNT PIC 9.
        10  REPEATING-CHILD OCCURS 1 TO 5 TIMES
                DEPENDING ON CHILD-COUNT.
            15  CHILD-NAME PIC X(6).

Compiling this using Enterprise Cobol v4.1 yields:

IGYGR1263-S "OCCURS DEPENDING ON" object "CHILD-COUNT" was defined as a table
element. The "DEPENDING ON" phrase was discarded.

IGYGR1116-S The "DEPENDING ON" object for table "REPEATING-CHILD" was invalid. The
"DEPENDING ON" phrase was discarded.

Not all parents are going to have the same number of children. How can this be addressed?

Edit: I suppose at its heart, this isn't really an XML question. I hit a wall just trying to build the working storage that I later hope to feed into XML GENERATE.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

恋你朝朝暮暮 2024-08-25 12:45:27

第一个答案摘要:你无法定义
COBOL 中的复杂 ODO,其中包含 ODO 对象
在一个表内。因此 XML 是不可能的
GENERATE 为每个生成不同数量的“子代”
“父母”的出现。你必须忍受固定的生活
表维度和空节点。

第二轮:您是否考虑过重新解析/重新构建
生成XML字符串以消除空节点?这
可能听起来有点奇怪,但可能并非如此
难的。看看下面的程序
它产生的输出...

   IDENTIFICATION DIVISION.                    
     PROGRAM-ID. EXAMPLE1.                     
   DATA DIVISION.                              
   WORKING-STORAGE SECTION.                    
   77  I                    PIC S9(4) BINARY.  
   77  XL                   PIC S9(4) BINARY.  
   77  XML-TAG              PIC X(34).         
   01  XML-DATA.                               
       05 XML-MSG-A         PIC X(8000).       
       05 XML-CHARS-A       PIC S9(4) BINARY.  
       05 XML-MSG-B         PIC X(8000).       
       05 XML-CHARS-B       PIC S9(4) BINARY.  
   01  SOURCE-REC.                             
       05  REPEATING-PARENT OCCURS 5 TIMES.    
           10  PARENT-NAME PIC X(7).           
           10  CHILD-COUNT PIC 9.              
           10  REPEATING-CHILD OCCURS 5 TIMES. 
               15  CHILD-NAME PIC X(6).        
   01  XML-STACK.                                 
       05 SP                PIC S9(4) BINARY.     
       05 STACK-REC         OCCURS 500 TIMES.     
          15 NODE-NAME      PIC X(31).            
          15 NODE-POS       PIC S9(4) BINARY.     
          15 NODE-IS-EMPTY  PIC X.                
             88 NODE-IS-EMPTY-YES VALUE 'Y'.       
             88 NODE-IS-EMPTY-NO  VALUE 'N'.       
          15 EMPTY-WHEN-IND      PIC X.                
             88 EMPTY-ZERO-OR-SPACE  VALUE 'Z'.   
             88 EMPTY-NEVER          VALUE 'N'.   
   PROCEDURE DIVISION.                            
       INITIALIZE SOURCE-REC.                     
       MOVE 'p-1'       TO PARENT-NAME (1)        
       MOVE 2           TO CHILD-COUNT (1)        
       MOVE 'c-1-1'     TO CHILD-NAME  (1 1)      
       MOVE 'c-1-2'     TO CHILD-NAME  (1 2)      
       MOVE 'p-2'       TO PARENT-NAME (2)        
       MOVE 0           TO CHILD-COUNT (2)        
       MOVE 'p-3'       TO PARENT-NAME (3)                        
       MOVE 1           TO CHILD-COUNT (3)                        
       MOVE 'c-3-1' TO CHILD-NAME  (3 1)                          

       XML GENERATE XML-MSG-A FROM SOURCE-REC COUNT IN XML-CHARS-A
       MOVE ZERO TO XML-CHARS-B                                   
       MOVE SPACES TO XML-MSG-B                                   
       XML PARSE XML-MSG-A(1:XML-CHARS-A)                         
           PROCESSING PROCEDURE CLEAN-UP                          
       PERFORM VARYING I FROM 1 BY 80 UNTIL I > XML-CHARS-B       
         DISPLAY XML-MSG-B (I:80)                                 
       END-PERFORM                                                
       GOBACK                                                     
       .                                                          
   CLEAN-UP SECTION.                                              
       COMPUTE XL = FUNCTION LENGTH (XML-TEXT)                    
       EVALUATE XML-EVENT                                         
       WHEN 'START-OF-ELEMENT'                                    
          ADD 1 TO SP                                             
          MOVE XML-TEXT(1:XL) TO NODE-NAME (SP)                      
          COMPUTE NODE-POS (SP) = XML-CHARS-B + 1              
          STRING '<' XML-TEXT(1:XL) '>' DELIMITED BY SIZE           
            INTO XML-TAG                                      
          MOVE XML-TAG TO XML-MSG-B (XML-CHARS-B + 1:XL + 2)  
          COMPUTE XML-CHARS-B = XML-CHARS-B + XL + 2          
          SET NODE-IS-EMPTY-YES (SP) TO TRUE                   
 *****    EVALUATE XML-TEXT(1:XL)                                   
 *****    WHEN 'CHILD-COUNT'                                  
 *****       SET EMPTY-NEVER (SP) TO TRUE                     
 *****    WHEN OTHER                                          
             SET EMPTY-ZERO-OR-SPACE (SP) TO TRUE             
 *****    END-EVALUATE                                        
       WHEN 'CONTENT-CHARACTERS'                              
          IF EMPTY-ZERO-OR-SPACE (SP) AND                     
             (XML-TEXT(1:XL) = ZERO OR XML-TEXT(1:XL) = SPACE)            
             CONTINUE                                         
          ELSE                                                
             SET NODE-IS-EMPTY-NO (SP) TO TRUE                 
             MOVE XML-TEXT(1:XL) TO XML-MSG-B (XML-CHARS-B + 1:XL)     
             COMPUTE XML-CHARS-B = XML-CHARS-B + XL              
          END-IF                                                 
       WHEN 'END-OF-ELEMENT'                                     
          IF NODE-IS-EMPTY-YES (SP)                               
             COMPUTE XML-CHARS-B = NODE-POS (SP) - 1              
             SUBTRACT 1 FROM SP                                  
          ELSE                                                   
             STRING '</' XML-TEXT(1:XL) '>' DELIMITED BY SIZE          
               INTO XML-TAG                                      
             MOVE XML-TAG TO XML-MSG-B (XML-CHARS-B + 1:XL + 3)  
             COMPUTE XML-CHARS-B = XML-CHARS-B + XL + 3          
             SUBTRACT 1 FROM SP                                  
             IF SP > ZERO                                        
               SET NODE-IS-EMPTY-NO (SP) TO TRUE                  
             ELSE                                                
               MOVE SPACES TO XML-MSG-B (XML-CHARS-B + 1:)       
             END-IF                                              
          END-IF                                                 
       END-EVALUATE         
       .                    

为您提供以下 XML 字符串(切成 80 个字符块)

<SOURCE-REC><REPEATING-PARENT><PARENT-NAME>p-1</PARENT-NAME><CHILD-COUNT>2</CHIL
D-COUNT><REPEATING-CHILD><CHILD-NAME>c-1-1</CHILD-NAME></REPEATING-CHILD><REPEAT
ING-CHILD><CHILD-NAME>c-1-2</CHILD-NAME></REPEATING-CHILD></REPEATING-PARENT><RE
PEATING-PARENT><PARENT-NAME>p-2</PARENT-NAME></REPEATING-PARENT><REPEATING-PAREN
T><PARENT-NAME>p-3</PARENT-NAME><CHILD-COUNT>1</CHILD-COUNT><REPEATING-CHILD><CH
ILD-NAME>c-3-1</CHILD-NAME></REPEATING-CHILD></REPEATING-PARENT></SOURCE-REC>   

所有空节点已被删除。

请注意上述程序中注释的代码行。通过重新激活这些您
可以保留空的 REPEATING-PARENT 节点。根据您的需求,
确定什么构成空节点可能稍微复杂一些。

无论如何,这可能会让你更接近你想要的地方。

干杯...

Summary of first answer: You cannot define
a complex ODO in COBOL where the ODO object is contained
within a table. Consequently it is not possible for XML
GENERATE to produce a varying number of "childern" for each
occurance of a "parent". You have to live with fixed
table dimensions and empty nodes.

Round two: Have you considered re-parsing/re-constructing the
generated XML string to eliminate the empty nodes? This
may sound a little odd but it may not be all that
difficult. Have a look at the following program and
the output it produces...

   IDENTIFICATION DIVISION.                    
     PROGRAM-ID. EXAMPLE1.                     
   DATA DIVISION.                              
   WORKING-STORAGE SECTION.                    
   77  I                    PIC S9(4) BINARY.  
   77  XL                   PIC S9(4) BINARY.  
   77  XML-TAG              PIC X(34).         
   01  XML-DATA.                               
       05 XML-MSG-A         PIC X(8000).       
       05 XML-CHARS-A       PIC S9(4) BINARY.  
       05 XML-MSG-B         PIC X(8000).       
       05 XML-CHARS-B       PIC S9(4) BINARY.  
   01  SOURCE-REC.                             
       05  REPEATING-PARENT OCCURS 5 TIMES.    
           10  PARENT-NAME PIC X(7).           
           10  CHILD-COUNT PIC 9.              
           10  REPEATING-CHILD OCCURS 5 TIMES. 
               15  CHILD-NAME PIC X(6).        
   01  XML-STACK.                                 
       05 SP                PIC S9(4) BINARY.     
       05 STACK-REC         OCCURS 500 TIMES.     
          15 NODE-NAME      PIC X(31).            
          15 NODE-POS       PIC S9(4) BINARY.     
          15 NODE-IS-EMPTY  PIC X.                
             88 NODE-IS-EMPTY-YES VALUE 'Y'.       
             88 NODE-IS-EMPTY-NO  VALUE 'N'.       
          15 EMPTY-WHEN-IND      PIC X.                
             88 EMPTY-ZERO-OR-SPACE  VALUE 'Z'.   
             88 EMPTY-NEVER          VALUE 'N'.   
   PROCEDURE DIVISION.                            
       INITIALIZE SOURCE-REC.                     
       MOVE 'p-1'       TO PARENT-NAME (1)        
       MOVE 2           TO CHILD-COUNT (1)        
       MOVE 'c-1-1'     TO CHILD-NAME  (1 1)      
       MOVE 'c-1-2'     TO CHILD-NAME  (1 2)      
       MOVE 'p-2'       TO PARENT-NAME (2)        
       MOVE 0           TO CHILD-COUNT (2)        
       MOVE 'p-3'       TO PARENT-NAME (3)                        
       MOVE 1           TO CHILD-COUNT (3)                        
       MOVE 'c-3-1' TO CHILD-NAME  (3 1)                          

       XML GENERATE XML-MSG-A FROM SOURCE-REC COUNT IN XML-CHARS-A
       MOVE ZERO TO XML-CHARS-B                                   
       MOVE SPACES TO XML-MSG-B                                   
       XML PARSE XML-MSG-A(1:XML-CHARS-A)                         
           PROCESSING PROCEDURE CLEAN-UP                          
       PERFORM VARYING I FROM 1 BY 80 UNTIL I > XML-CHARS-B       
         DISPLAY XML-MSG-B (I:80)                                 
       END-PERFORM                                                
       GOBACK                                                     
       .                                                          
   CLEAN-UP SECTION.                                              
       COMPUTE XL = FUNCTION LENGTH (XML-TEXT)                    
       EVALUATE XML-EVENT                                         
       WHEN 'START-OF-ELEMENT'                                    
          ADD 1 TO SP                                             
          MOVE XML-TEXT(1:XL) TO NODE-NAME (SP)                      
          COMPUTE NODE-POS (SP) = XML-CHARS-B + 1              
          STRING '<' XML-TEXT(1:XL) '>' DELIMITED BY SIZE           
            INTO XML-TAG                                      
          MOVE XML-TAG TO XML-MSG-B (XML-CHARS-B + 1:XL + 2)  
          COMPUTE XML-CHARS-B = XML-CHARS-B + XL + 2          
          SET NODE-IS-EMPTY-YES (SP) TO TRUE                   
 *****    EVALUATE XML-TEXT(1:XL)                                   
 *****    WHEN 'CHILD-COUNT'                                  
 *****       SET EMPTY-NEVER (SP) TO TRUE                     
 *****    WHEN OTHER                                          
             SET EMPTY-ZERO-OR-SPACE (SP) TO TRUE             
 *****    END-EVALUATE                                        
       WHEN 'CONTENT-CHARACTERS'                              
          IF EMPTY-ZERO-OR-SPACE (SP) AND                     
             (XML-TEXT(1:XL) = ZERO OR XML-TEXT(1:XL) = SPACE)            
             CONTINUE                                         
          ELSE                                                
             SET NODE-IS-EMPTY-NO (SP) TO TRUE                 
             MOVE XML-TEXT(1:XL) TO XML-MSG-B (XML-CHARS-B + 1:XL)     
             COMPUTE XML-CHARS-B = XML-CHARS-B + XL              
          END-IF                                                 
       WHEN 'END-OF-ELEMENT'                                     
          IF NODE-IS-EMPTY-YES (SP)                               
             COMPUTE XML-CHARS-B = NODE-POS (SP) - 1              
             SUBTRACT 1 FROM SP                                  
          ELSE                                                   
             STRING '</' XML-TEXT(1:XL) '>' DELIMITED BY SIZE          
               INTO XML-TAG                                      
             MOVE XML-TAG TO XML-MSG-B (XML-CHARS-B + 1:XL + 3)  
             COMPUTE XML-CHARS-B = XML-CHARS-B + XL + 3          
             SUBTRACT 1 FROM SP                                  
             IF SP > ZERO                                        
               SET NODE-IS-EMPTY-NO (SP) TO TRUE                  
             ELSE                                                
               MOVE SPACES TO XML-MSG-B (XML-CHARS-B + 1:)       
             END-IF                                              
          END-IF                                                 
       END-EVALUATE         
       .                    

Gives you the following XML string (cut into 80 character chunks)

<SOURCE-REC><REPEATING-PARENT><PARENT-NAME>p-1</PARENT-NAME><CHILD-COUNT>2</CHIL
D-COUNT><REPEATING-CHILD><CHILD-NAME>c-1-1</CHILD-NAME></REPEATING-CHILD><REPEAT
ING-CHILD><CHILD-NAME>c-1-2</CHILD-NAME></REPEATING-CHILD></REPEATING-PARENT><RE
PEATING-PARENT><PARENT-NAME>p-2</PARENT-NAME></REPEATING-PARENT><REPEATING-PAREN
T><PARENT-NAME>p-3</PARENT-NAME><CHILD-COUNT>1</CHILD-COUNT><REPEATING-CHILD><CH
ILD-NAME>c-3-1</CHILD-NAME></REPEATING-CHILD></REPEATING-PARENT></SOURCE-REC>   

All of the empty nodes have been removed.

Note the commented lines of code in the above program. By re-activating these you
can preserve the empty REPEATING-PARENT nodes. Depending on your needs, the
determination of what constitutes an empty node may be somewhat more complex.

At any rate this might get you a little closer to where you want to be.

Cheers...

浮华 2024-08-25 12:45:27

我认为问题在于必须定义 CHILD-COUNT
在传递给 XML GENERATE 的记录结构之外。像这样的东西:


01  CHILD-COUNT PIC 9.
01  SOURCE-REC. 
    05  REPEATING-PARENT OCCURS 5 TIMES. 
        10  PARENT-NAME PIC X(7). 
        10  CHILD-COUNTER PIC 9. 
        10  REPEATING-CHILD OCCURS 1 TO 5 TIMES 
                DEPENDING ON CHILD-COUNT. 
            15  CHILD-NAME PIC X(6).

然后在 XML GENERATE 之前你必须做一些事情
做作的比如:


MOVE CHILD-COUNT TO CHILD-COUNTER (PARENT-COUNT)

如果您想保留 REPEATING-CHILD 出现的次数,

这可能不是您想要看到的,因为它几乎
意味着您必须为每个人拥有相同数量的受抚养子女
REPEATING-PARENT 出现。

I think the problem is that the CHILD-COUNT must be defined
outside of the record structure passed to XML GENERATE. Something like:


01  CHILD-COUNT PIC 9.
01  SOURCE-REC. 
    05  REPEATING-PARENT OCCURS 5 TIMES. 
        10  PARENT-NAME PIC X(7). 
        10  CHILD-COUNTER PIC 9. 
        10  REPEATING-CHILD OCCURS 1 TO 5 TIMES 
                DEPENDING ON CHILD-COUNT. 
            15  CHILD-NAME PIC X(6).

Then just before the XML GENERATE you would have to do something
hokey such as:


MOVE CHILD-COUNT TO CHILD-COUNTER (PARENT-COUNT)

if you want to retain the number of occurs for REPEATING-CHILD

This is probably not what you wanted to see because it pretty much
means you must to have the same number of dependant children for each
REPEATING-PARENT occurance.

白鸥掠海 2024-08-25 12:45:27

我认为你应该完全失去依赖。它不会节省内存,并且您可以通过确保它们的下标在 1 到相应的 CHILD-COUNTER 范围内来轻松寻址有效的 REPEATING-CHILD 项。

I think you should lose the DEPENDING ON altogether. It doesn't save memory, and you can just as easily address valid REPEATING-CHILD items by making sure their subscripts are in the range from 1 to the corresponding CHILD-COUNTER.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文