2012-06-18 154 views
1

我試圖訪問下面的示例XML中的整個「< mynode>」節點,包括開始和結束標記。我需要將XML片段作爲XML存儲在數據庫中。COBOL XML PARSE等價於innerXML?

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

我可以訪問XML解析功能,這就是我如何被訪問節點的值,但我不知道如何使用它來訪問整個節點。

想到的一個選擇是記錄文檔位置,其中元素開始和元素結束XML-TEXT ='b',然後取出文檔的那一部分,但看起來不雅觀。有沒有更好的辦法?

編輯:我計算了我讀到文檔中的多少個字符,並在到達「< mynode>」節點的開始和結束時存儲該值。

然後,我可以用

STRING MY-DOCUMENT(MYNODE-START-POSE, (MYNODE-NODE-FINISH - MYNODE-NODE-START)) 
    DELIMITED BY SIZE 
    INTO MY-AREA 

回答

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!

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

如果您使用的是IBM's Enterprise COBOL,則表示您有XML PARSE語句可用。解析器生成事件並將您可以使用的special registers填充到govern execution of your code(由於某些原因最後一個環節不能正常工作,它應該帶你到頁面上的「控制流」標籤)

如果你需要「修剪」樹形結構的部分,包括標籤和數據,那麼您可能需要解析原始數據,填充結構,然後使用XML GENERATE來獲取所需的XML數據流。它看起來並不像解析器會告訴你每個事件發生的原始XML數據流中的位置,至少看起來沒有一個特殊的寄存器填充了該值。

0

我現在可能有點遲到了,但是我們使用了Redvers COBOL XML Interface分析器,它具有「ASIS」功能,可將節點/父元素的全部內容讀入單個COBOL副本字段中 - 包含任何XML標記上和下級元素。這是一個DOM風格的解析器。生成器模塊可以做相反的事情,使您能夠將預先準備好的XML加載到實例文檔中。