COBOL XML PARSE相当于innerXML?

时间:2012-06-18 15:40:47

标签: xml cobol

我正在尝试访问整个“< mynode>”下面的示例XML中的节点,包括开始和结束标记。我需要将XML片段作为XML存储在数据库中。

<a>
  <mynode >
   <c>Content</c>
   <c>More content</c>
  </mynode >
</a>

我可以访问XML PARSE函数,这就是我访问节点值的方式,但我不知道如何使用它来访问整个节点。

我想到的一个选项是记录元素开头和元素结尾XML-TEXT ='b'的文档位置,然后获取文档的那部分,但这看起来不够优雅。还有更好的方法吗?

编辑:我计算了我在文档中读取了多少个字符,并在到达“&lt; mynode&gt;”的开头和结尾时存储该值节点。

然后我可以使用

访问该文档
STRING MY-DOCUMENT(MYNODE-START-POSE, (MYNODE-NODE-FINISH - MYNODE-NODE-START)) 
     DELIMITED BY SIZE
     INTO MY-AREA

4 个答案:

答案 0 :(得分:3)

如果您使用IBM's Enterprise COBOL,则可以使用XML PARSE语句。解析器生成事件并填充special registersgovern execution of your code可供您使用XML GENERATE(由于某种原因,最后一个链接无法正常工作,它应该会带您进入该页面上的“控制流”标记)

如果需要“修剪”树结构的某些部分(包括标记和数据),则可能需要解析原始数据,填充结构,并使用{{3}}获取所需的XML数据流。看起来解析器不会告诉您原始XML数据流中每个事件发生的位置,至少似乎没有一个特殊的寄存器可以填充该值。

答案 1 :(得分:2)

COBOL XML PARSE不提供位置信息(AFAIK)。确定偏移位置在哪里 发生给定事件是不可能的。感兴趣的标签的文本搜索 必然会导致大量问题 - 甚至不想去那里......

我能想到的下一个可能性是在解析时构造感兴趣的XML片段文档 原始文件。片段完成后,将其写入XML数据库。

下面的示例程序说明了如何进行此操作。这个程序需要一个 XML-SOURCE文档并解析它寻找interst事件(例如'b'标签)。当这样的标签 发现它开始构建一个片段文档(XML-FRAGMENT),直到找到结束标记。在 此时输出片段并开始搜索下一个片段。

   IDENTIFICATION DIVISION.                   
   PROGRAM-ID. XMLTEST.                       
   DATA DIVISION.                             
   WORKING-STORAGE SECTION.

   77  XL                   PIC S9(4) BINARY. 

   01.                      PIC X.            
       88 XML-EXTRACT-NO    VALUE 'N'.        
       88 XML-EXTRACT-YES   VALUE 'Y'.        

   01.                                        
       05 XML-FRAGMENT      PIC X(8000).      
       05 XML-CHARS         PIC S9(4) BINARY. 

   01  XML-SOURCE           PIC X(8000). 

   PROCEDURE DIVISION.                                         
   MAINLINE SECTION.   

       MOVE '<a><b><c>Content</c><c>More content</c></b></a>'
         TO XML-SOURCE                                         

       SET XML-EXTRACT-NO TO TRUE                              
       XML PARSE XML-SOURCE                                    
           PROCESSING PROCEDURE XTRACT                         
       GOBACK                                                  
       .                                                       
   XTRACT SECTION.                                             
       COMPUTE XL = FUNCTION LENGTH (XML-TEXT)                 
       EVALUATE XML-EVENT                                      
       WHEN 'START-OF-ELEMENT'
  *
  *       New XML element: Ignore it, add to existing fragment
  *       or start a new fragment...
  *                                                                 
          IF XML-TEXT(1:XL) = 'b' OR XML-EXTRACT-YES           
             IF XML-EXTRACT-NO                                 
                MOVE ZERO TO XML-CHARS                         
                SET XML-EXTRACT-YES TO TRUE                    
             END-IF                                            
             STRING '<' XML-TEXT(1:XL) '>' DELIMITED BY SIZE        
               INTO XML-FRAGMENT(XML-CHARS + 1 : XL + 2)            
             COMPUTE XML-CHARS = XML-CHARS + XL + 2                 
          END-IF                                                    
       WHEN 'END-OF-ELEMENT'
  *
  *       End of event: Add to XML fragment, ignore fragment or
  *                     output complete fragment and start search
  *                     for a new one...
  *                                        
          IF XML-EXTRACT-YES                                        
             STRING '</' XML-TEXT(1:XL) '>' DELIMITED BY SIZE       
               INTO XML-FRAGMENT(XML-CHARS + 1 : XL + 3)            
             COMPUTE XML-CHARS = XML-CHARS + XL + 3                 
          END-IF

          IF XML-TEXT(1:XL) = 'b'                                   
  *                                                                 
  *          End of fragment write to database (or whatever)               
  *                                                                 
             DISPLAY XML-FRAGMENT(1:XML-CHARS) 
             SET XML-EXTRACT-NO TO TRUE        
          END-IF
       WHEN 'CONTENT-CHARACTERS'
  *
  *       Add event data to fragment or just ignore it...
  *
  *       Depening on the structure of your XML docuemnt you may
  *       need to react to addtional EVENTS such as CDATA to ensure
  *       proper tag construction.
  *
          IF XML-EXTRACT-YES                                        
             MOVE XML-TEXT(1:XL) TO XML-FRAGMENT(XML-CHARS + 1 : XL)
             COMPUTE XML-CHARS = XML-CHARS + XL                     
          END-IF                                                    

       END-EVALUATE                            
       .                                       

此程序示例的输出是:

 <b><c>Content</c><c>More content</c></b>

这不是您可能一直在寻找的单行解决方案,但您必须记住这是COBOL!

答案 2 :(得分:1)

在任何语言中,XML解析都有点棘手。我建议为您的特定COBOL环境找到解析器库。 This article简要概述了XML解析格局。考虑一下是否需要传递XML文件,随意提取所需信息(SAX方法适合您)或者是否要将XML加载到内存中并遍历其结构(您希望访问DOM [文档对象模型])。

事实上,您的COBOL方言可能有XML support built in(我的旧COBOL 85编译器没有的东西)和XML PARSE语句。

这里有点information from the Micro Focus world

答案 3 :(得分:0)

我现在可能有点迟到了,但是我们使用Redvers COBOL XML Interface解析器,它具有“ASIS”功能,可以将节点/父元素的整个内容读入单个COBOL字帖字段 - 完成任何XML标记和从属元素。这是一个DOM风格的解析器。生成器模块可以执行相反的操作,使您能够将预先准备好的XML加载到实例文档。