RPG で XML 文書を処理する (SAX編 その 2)

RPG で XML 文書を処理する (SAX編 その 1)」に引き続いて XML-SAX 命令についてです。

"MC Press Online - RPG Has SAX Appeal!"に載っていたもうひとつのサンプルプログラムも動かしてみました。

修正点、考慮点については前回と同様です。

こちらのサンプルプログラムについては"MC Press Online - RPG Has SAX Appeal!"に解説が載っているのでそちらをご参照ください。

     H Option(*NoDebugIO : *SrcStmt )

     DMCPXMLEX5        Pr
     D   XML_Source                  30A   const options(*varsize)
     DMCPXMLEX5        Pi
     D   XML_Source                  30A   const options(*varsize)

      // This count is populated by XML-INTO whenever the INTO
      //   variable is an array
     D progStatus     SDS
     D   xmlElements                 20i 0 Overlay(progStatus: 372)

(D)  D MySAXHandler    Pr            10i 0
     D   commArea                           Like(dummyCommArea)
     D   event                       10i 0  Value
     D   pstring                       *    Value
     D   stringLen                   20i 0  Value
     D   exceptionId                 10i 0  Value

     D RmvWhitespace   pr         65535a   Varying
     D   input                    65535a   Varying Const

     D category        DS                  Qualified Dim(20)
     D   code                         2a
     D   catDescr                    20a
     D   product                           LikeDS(product) Dim(50)

     D product         DS                  Qualified
     D   code                         4a
(A)  D   descrType                    5a   Dim(2)
     D   description                600a   Dim(2)
     D   mSRP                         7p 2
     D   sellPrice                    7p 2
     D   qtyOnHand                    5i 0

     D*XML_Source      S            256a   Varying
     D*                                    Inz('/home/xmltest/XML/Example6.xml')

      // Short version of Description for display purposes
     D dispDescription...
     D                 S             40a

     D dummyCommArea   S              1a
     D i               S              5i 0
     D p               S              5i 0

     d option          s             25a

      /Free

(B)    XML-INTO category
                %XML(XML_Source: 'case=any doc=file allowextra=yes +
                                  allowmissing=yes');

       // XML-INTO has filled the category array
       //   Next we use XML-SAX to fill in the missing type details
(C)    XML-SAX %HANDLER(MySAXHandler: dummyCommArea)
                %XML(XML_Source: 'doc=file ccsid=ucs2');

       Dsply ('xmlElements = ' + %char(xmlElements) );

       // The XML parser's element count is used to control the loop
(J)    For i = 1 to xmlElements;
         Dsply ('Cat: ' + category(i).code + ' ' +
                category(i).catDescr );
         For p = 1 to %Elem(category.product);
           If category(i).product(p).code = *Blanks;
             Leave;      // Exit once blank product code entry located
           Else;
             // Process the current product entry
             dispDescription = category(i).product(p).description(1);
             Dsply ('Product: ' +  dispDescription);
             Dsply ('Type: ' + category(i).product(p).descrType(1));

             // If second description is present, display details
(K)          If category(i).product(p).description(2) <> *Blanks;
               dispDescription = category(i).product(p).description(2);
               Dsply ('Product: ' +  dispDescription);
               Dsply ('Type: ' + category(i).product(p).descrType(2));
             EndIf;

           EndIf;

         EndFor;
       EndFor;

       *InLR = *On;

      /End-Free


       // SAX handler
     P MySAXHandler    B
     D                 PI            10i 0
     D   commArea                           Like(dummyCommArea)
     D   event                       10i 0  Value
     D   pstring                       *    Value
     D   stringLen                   20i 0  Value
     D   exceptionId                 10i 0  Value

(F)  D*string          S          65535a    Based(pstring)
(F)  D string          S          16383c    Based(pstring)

     D data            S          65535a    Varying

      // Static variables used by handler logic
     D catIndex        S             10i 0  Static
     D prodIndex       S             10i 0  Static
     D descIndex       S              5i 0  Static
     D waitingForType  S               n    Static

      // Constants to identify the element and attribute
      //   names we are interested in.
     D categorElem     C                   'Category'
     D prodElem        C                   'Product'
     D descrElem       C                   'Description'
     D typeAttr        C                   'type'

      /free
             // If any data is supplied strip whitespace from it
             //   otherwise just return to parser
(E)       If stringLen > 0;
             stringLen = ( stringLen / 2 );
             data = rmvWhiteSpace(%subst(%char(string) : 1 : stringLen));
         //  data = RmvWhiteSpace(%subst(string : 1 : stringLen));  (This is original)
          Else;
             return 0;
          endif;

          Select;
            When event = *XML_START_ELEMENT;
              // Whenever we start a new element, we increment the index
              //   for that level and zero the index for the next level.

(G)           Select;
                When data = categorElem;
                  catIndex += 1;
                  prodIndex = 0;
                When data = prodElem;
                  prodIndex += 1;
                  descIndex = 0;
                When data = descrElem;
                  descIndex += 1;
              EndSl;

(H)         When event = *XML_ATTR_NAME;
              // Turn "waiting" indicator when beginning a "type" attribute
              If data = typeAttr;
                waitingForType = *On;
              EndIf;

(I)         When event = *XML_ATTR_CHARS;
              // If waiting for type information then store type
              if waitingForType;
                category(catIndex).product(prodIndex).descrType(descIndex)
                  = data;
                waitingForType = *Off;
              EndIf;

          EndSl;

       return 0;

      /end-free
     P                 E

      // The following procedure returns a string that is the same
      //   as the input string except that strings of whitespace i.e.
      //   x'15'=newline  x'05'=tab     x'0D'=carriage-return
      //   x'25'=linefeed and x'40'=blank are converted to a single blank.

     P RmvWhiteSpace   b
     D                 pi         65535a   varying
     D   input                    65535a   varying const

     D output          s                   like(input) inz('')

     D whitespaceChr   C                   x'15050D2540'

     D c               s              1a
     D i               s             10i 0
     D inWhitespace    s               n   INZ(*OFF)

      /free
       // copy all non-whitespace characters to the return value
       for i = 1 to %len(input);
          c = %subst(input : i : 1);
          if %scan(c : whitespaceChr) > 0;
             // If this is a new set of whitespace, add one blank
             if inWhitespace = *OFF;
                inWhitespace = *ON;
                output += ' ';
             endif;
          else;
             // Not handling whitespace now.  Add character to output
             inWhitespace = *OFF;
             output += c;
          endif;
       endfor;

       return output;

      /end-free

     P RmvWhiteSpace   e

[Top Pageに戻る]

Ads by TOK2