1

以下のサンプルXMLの「<mynode>」ノード全体にアクセスしようとしています。これには、開始タグと終了タグが含まれます。そのXMLスニペットをXMLとしてデータベースに保存する必要があります。

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

XML PARSE関数にアクセスでき、それがノード値にアクセスする方法ですが、ノード全体にアクセスするためにそれを使用する方法がわかりません。

頭に浮かんだオプションの1つは、要素の開始と要素の終了XML-TEXT ='b'であるドキュメントの場所を記録し、ドキュメントのその部分を取得することでしたが、それはエレガントではないようです。もっと良い方法はありますか?

編集:ドキュメントに読み込んだ文字数を数え、「<mynode>」ノードの最初と最後に到達したときにその値を保存します。

次に、次のコマンドでドキュメントにアクセスできます

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

4 に答える 4

3

IBMのEnterpriseCOBOLを使用している場合は、XMLPARSEステートメントを使用できます。パーサーはイベントを生成し、コードの実行を管理するために使用できる特殊レジスターにデータを取り込みます。 (最後のリンクが正しく機能しない何らかの理由で、そのページの「制御フロー」タグに移動するはずです)

タグやデータなど、ツリー構造の一部を「整理」する必要がある場合は、元の構造を解析し、構造にデータを入力し、XMLGENERATEを使用して必要なXMLデータストリームを取得することをお勧めします。パーサーが各イベントが発生する元のXMLデータストリーム内の場所を教えてくれるようには見えません。少なくとも、その値が入力される特殊レジスターはないようです。

于 2012-06-19T01:51:31.900 に答える
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であることを覚えておく必要があります!

于 2012-06-19T20:58:18.747 に答える
1

XML解析は、どの言語でも少し注意が必要です。特定のCOBOL環境用のパーサーライブラリを見つけることをお勧めします。 この記事では、XML解析ランドスケープの概要を説明します。XMLファイルを一度渡す必要があるのか​​、必要な情報を抽出する必要があるのか​​(SAXアプローチが有効です)、またはXMLをメモリにロードしてその構造をトラバースする必要があるのか​​(DOMにアクセスする必要があるのか​​)を考えてください。ドキュメントオブジェクトモデル])。

実際、COBOLダイアレクトには、ステートメントとともにXMLサポートが組み込まれている場合があります(私の古いCOBOL 85コンパイラにはなかったもの) 。XML PARSE

そして、ここにMicroFocusの世界からのちょっとした情報があります。

于 2012-06-18T18:25:04.380 に答える
0

この返信には少し遅れるかもしれませんが、ノード/親要素のコンテンツ全体を単一のCOBOLコピーブックフィールドに読み取る「ASIS」機能を備えたRedvers COBOLXMLインターフェイスパーサーを使用します-任意のXMLマークを付けて-上および従属要素。これはDOMスタイルのパーサーです。ジェネレータモジュールは逆のことを行うことができ、事前に準備されたXMLをインスタンスドキュメントにロードする機能を提供します。

于 2017-01-19T14:59:39.960 に答える