Sign in

docs Examples

input_xml

input_xml

**FREE

///
// \brief XML Input Provider
// 
// This module implements the input provider procedures and parses the passed
// XML file for item entries via the XML built-in functions.
//
// The xml handler procedure looks for an XML entry "item" which should contain
// the XML entries id, description and manufacturer. All item values should be
// XML characters (not XML attributes).
// 
// \author Mihael Schmidt
// \date 20.11.2016
///


ctl-opt nomain;


//-------------------------------------------------------------------------------------------------
// Data Structures
//-------------------------------------------------------------------------------------------------
/include 'input_t.rpgle'

dcl-ds input_xml_t qualified template;
  path char(1024);
  loaded ind;
  items likeds(item_t) dim(100);
  itemCount int(10);
  currentItemIndex int(10);
end-ds;

dcl-ds xmldata_t qualified template;
  itemCount int(10);
  items likeds(item_t) dim(100);
  lastElement char(100);
end-ds;


//-------------------------------------------------------------------------------------------------
// Prototypes
//-------------------------------------------------------------------------------------------------
/include 'input_xml_h.rpgle'

dcl-pr xmlHandler int(10);
  commArea likeds(xmldata_t);
  event int(10) value;
  string pointer value;
  stringLen int(20) value;
  exceptionId int(10) value;
end-pr;

dcl-pr getNextItem likeds(item_t);
  userData likeds(input_xml_t);
end-pr;


//-------------------------------------------------------------------------------------------------
// Procedures
//-------------------------------------------------------------------------------------------------
dcl-proc input_xml_load export;
  dcl-pi *N likeds(item_t);
    inputProvider pointer const;
  end-pi;

  dcl-ds inputDs likeds(input_t) based(inputProvider);
  dcl-ds userData likeds(input_xml_t) based(inputDs.userData);
  dcl-ds item likeds(item_t);

  item = getNextItem(userData);

  return item;
end-proc;


dcl-proc input_xml_finalize export;
  dcl-pi *N;
    inputProvider pointer;
  end-pi;

  dcl-ds inputDs likeds(input_t) based(inputProvider);
  dcl-ds userDataDs likeds(input_xml_t) based(inputDs.userData);

  // clean up allocated memory for the input provider
  dealloc inputDs.userData;
  dealloc(n) inputProvider;
end-proc;

dcl-proc input_xml_create export;
  dcl-pi *N pointer;
    userData pointer const options(*string);
  end-pi;

  dcl-s ptr pointer;
  dcl-ds inputDs likeds(input_t) based(ptr);
  dcl-s userDataPtr pointer;
  dcl-ds userDataDs likeds(input_xml_t) based(userDataPtr);

  ptr = %alloc(%size(input_t));

  userDataPtr = %alloc(%size(input_xml_t));
  clear userDataDs;
  userDataDs.path = %str(userData);
  userDataDs.loaded = *off;
   
  inputDs.userData = userDataPtr;
  inputDs.proc_load = %paddr('input_xml_load');
  inputDs.proc_finalize = %paddr('input_xml_finalize');

  return ptr;
end-proc;

///
// Get next item from XML file
//
// This procedure loads the data from the XML file if it has not been loaded yet.
// 
// It returns the next item. The current item index is stored in the passed
// user data data structure.
//
// \param Input provider user data
//
// \return next item or an empty item data structure if no more items has been loaded
///
dcl-proc getNextItem;
  dcl-pi *N likeds(item_t);
    userData likeds(input_xml_t);
  end-pi;
  
  dcl-ds xmlCommArea likeds(xmldata_t) static;
  dcl-ds item likeds(item_t);
  
  clear item;
  
  if (userData.loaded = *off);
    clear xmlCommArea;
    xml-sax %handler(xmlHandler : xmlCommArea) %xml(%trimr(userData.path) : 'doc=file');
    userData.loaded = *on;
    userData.itemCount = xmlCommArea.itemCount;
    userData.items = xmlCommArea.items;
  endif;
  
  userData.currentItemIndex += 1;
  if (userData.currentItemIndex > userData.itemCount);
    userData.currentItemIndex = 0;
    userData.loaded = *off;
    clear userData.items;
    userData.itemCount = 0;
  else;
    item = userData.items(userData.currentItemIndex);
  endif;
  
  return item;
end-proc;

///
// XML handler procedure for loading xml item data
//
// All item data and item count is stored in the communication area data
// structure.
///
dcl-proc xmlHandler;
  dcl-pi *N int(10);
    commArea likeds(xmldata_t);
    event int(10) value;
    string pointer value;
    stringLen int(20) value;
    exceptionId int(10) value;
  end-pi;

  dcl-s value char(1000) based(string);
  dcl-s tmp char(100);
  dcl-s retVal int(10);
  dcl-s fieldLength uns(10);

  select;
    when (event = *XML_START_ELEMENT);
      commArea.lastElement = %subst(value : 1 : stringLen);

      if (commArea.lastElement = 'item');
        commArea.itemCount += 1;
      endif;

    when (event = *XML_CHARS);
      if (commArea.lastElement = 'id');
        commArea.items(commArea.itemCount).id = %trim(%subst(value : 1 : stringLen));
      elseif (commArea.lastElement = 'description');
        commArea.items(commArea.itemCount).description = %trim(%subst(value : 1 : stringLen));
      elseif (commArea.lastElement = 'manufacturer');
        commArea.items(commArea.itemCount).vendor = %trim(%subst(value : 1 : stringLen));
      endif;

    when (event = *XML_END_ELEMENT);
      commArea.lastElement = *blank;

  endsl;

  return retVal;
end-proc;