In this module, we will explore how to handle XML data in RPG programming. XML (eXtensible Markup Language) is a widely-used format for data representation and exchange. Understanding how to parse, generate, and manipulate XML data is crucial for integrating RPG applications with other systems and technologies.

Objectives

By the end of this module, you will:

  • Understand the basics of XML.
  • Learn how to parse XML data in RPG.
  • Learn how to generate XML data in RPG.
  • Work with practical examples and exercises to reinforce your understanding.

What is XML?

XML stands for eXtensible Markup Language. It is a markup language much like HTML but is designed to store and transport data. XML is both human-readable and machine-readable, making it an ideal format for data interchange.

Key Features of XML:

  • Self-descriptive: XML documents contain metadata that describes the data.
  • Hierarchical structure: Data is organized in a tree-like structure.
  • Platform-independent: XML can be used across different systems and platforms.
  • Extensible: Users can define their own tags and structure.

Example of an XML Document:

<inventory>
    <item>
        <id>1</id>
        <name>Widget</name>
        <quantity>100</quantity>
        <price>9.99</price>
    </item>
    <item>
        <id>2</id>
        <name>Gadget</name>
        <quantity>50</quantity>
        <price>19.99</price>
    </item>
</inventory>

Parsing XML in RPG

Parsing XML involves reading an XML document and extracting the data. In RPG, we can use the XML-INTO opcode to parse XML data into a data structure.

Example: Parsing XML Data

Let's parse the example XML document into an RPG data structure.

Step-by-Step Explanation:

  1. Define the Data Structure:

    Dcl-Ds Item Qualified;
        id       Int(10);
        name     Char(20);
        quantity Int(10);
        price    Packed(7:2);
    End-Ds;
    
    Dcl-Ds Inventory Qualified;
        item     LikeDs(Item) Dim(100);
    End-Ds;
    
  2. XML Data:

    Dcl-S xmlData Char(1000);
    xmlData = '<inventory>
                  <item>
                      <id>1</id>
                      <name>Widget</name>
                      <quantity>100</quantity>
                      <price>9.99</price>
                  </item>
                  <item>
                      <id>2</id>
                      <name>Gadget</name>
                      <quantity>50</quantity>
                      <price>19.99</price>
                  </item>
               </inventory>';
    
  3. Parse the XML Data:

    Xml-Into Inventory %Xml(xmlData: 'case=any');
    
  4. Access the Parsed Data:

    Dcl-S i Int(10);
    For i = 1 to %Elem(Inventory.item);
        If Inventory.item(i).id <> 0;
            Dsply ('ID: ' + %Char(Inventory.item(i).id));
            Dsply ('Name: ' + Inventory.item(i).name);
            Dsply ('Quantity: ' + %Char(Inventory.item(i).quantity));
            Dsply ('Price: ' + %Char(Inventory.item(i).price));
        EndIf;
    EndFor;
    

Explanation:

  • Data Structure Definition: We define a data structure Item to represent each item and an array Inventory to hold multiple items.
  • XML Data: We store the XML data in a character variable xmlData.
  • XML-INTO Opcode: We use the XML-INTO opcode to parse the XML data into the Inventory data structure.
  • Accessing Data: We loop through the Inventory array and display the parsed data.

Generating XML in RPG

Generating XML involves creating an XML document from RPG data structures. We can use the XML-SAX opcode to generate XML data.

Example: Generating XML Data

Let's generate an XML document from an RPG data structure.

Step-by-Step Explanation:

  1. Define the Data Structure:

    Dcl-Ds Item Qualified;
        id       Int(10);
        name     Char(20);
        quantity Int(10);
        price    Packed(7:2);
    End-Ds;
    
    Dcl-Ds Inventory Qualified;
        item     LikeDs(Item) Dim(2);
    End-Ds;
    
  2. Populate the Data Structure:

    Inventory.item(1).id = 1;
    Inventory.item(1).name = 'Widget';
    Inventory.item(1).quantity = 100;
    Inventory.item(1).price = 9.99;
    
    Inventory.item(2).id = 2;
    Inventory.item(2).name = 'Gadget';
    Inventory.item(2).quantity = 50;
    Inventory.item(2).price = 19.99;
    
  3. Generate XML Data:

    Dcl-S xmlData Char(1000);
    Dcl-S xmlLength Int(10);
    
    xmlLength = %Len(xmlData);
    
    Xml-Sax %Handler('MySaxHandler') %Data(xmlData: xmlLength);
    
    Dcl-Proc MySaxHandler;
        Dcl-Pi *N;
            eventType Int(10);
            eventData Pointer;
        End-Pi;
    
        Select;
            When eventType = XML_START_DOCUMENT;
                xmlData = '<?xml version="1.0" encoding="UTF-8"?>';
            When eventType = XML_START_ELEMENT;
                xmlData += '<' + %Str(eventData) + '>';
            When eventType = XML_END_ELEMENT;
                xmlData += '</' + %Str(eventData) + '>';
            When eventType = XML_CHARACTERS;
                xmlData += %Str(eventData);
        EndSelect;
    End-Proc;
    

Explanation:

  • Data Structure Definition: We define a data structure Item to represent each item and an array Inventory to hold multiple items.
  • Populate Data Structure: We populate the Inventory data structure with sample data.
  • XML-SAX Opcode: We use the XML-SAX opcode to generate XML data. The MySaxHandler procedure handles the SAX events to construct the XML document.

Practical Exercise

Exercise: Parse and Generate XML

  1. Task: Write an RPG program to parse the following XML data and then generate an XML document from the parsed data.

    <library>
        <book>
            <title>The Great Gatsby</title>
            <author>F. Scott Fitzgerald</author>
            <year>1925</year>
        </book>
        <book>
            <title>1984</title>
            <author>George Orwell</author>
            <year>1949</year>
        </book>
    </library>
    
  2. Steps:

    • Define the data structures to represent the XML data.
    • Parse the XML data into the data structures.
    • Generate an XML document from the parsed data.

Solution:

Dcl-Ds Book Qualified;
    title  Char(50);
    author Char(50);
    year   Int(10);
End-Ds;

Dcl-Ds Library Qualified;
    book LikeDs(Book) Dim(100);
End-Ds;

Dcl-S xmlData Char(1000);
xmlData = '<library>
              <book>
                  <title>The Great Gatsby</title>
                  <author>F. Scott Fitzgerald</author>
                  <year>1925</year>
              </book>
              <book>
                  <title>1984</title>
                  <author>George Orwell</author>
                  <year>1949</year>
              </book>
           </library>';

Xml-Into Library %Xml(xmlData: 'case=any');

Dcl-S i Int(10);
For i = 1 to %Elem(Library.book);
    If Library.book(i).title <> '';
        Dsply ('Title: ' + Library.book(i).title);
        Dsply ('Author: ' + Library.book(i).author);
        Dsply ('Year: ' + %Char(Library.book(i).year));
    EndIf;
EndFor;

Dcl-S xmlOutput Char(1000);
Dcl-S xmlLength Int(10);

xmlLength = %Len(xmlOutput);

Xml-Sax %Handler('MySaxHandler') %Data(xmlOutput: xmlLength);

Dcl-Proc MySaxHandler;
    Dcl-Pi *N;
        eventType Int(10);
        eventData Pointer;
    End-Pi;

    Select;
        When eventType = XML_START_DOCUMENT;
            xmlOutput = '<?xml version="1.0" encoding="UTF-8"?>';
        When eventType = XML_START_ELEMENT;
            xmlOutput += '<' + %Str(eventData) + '>';
        When eventType = XML_END_ELEMENT;
            xmlOutput += '</' + %Str(eventData) + '>';
        When eventType = XML_CHARACTERS;
            xmlOutput += %Str(eventData);
    EndSelect;
End-Proc;

Explanation:

  • Data Structure Definition: We define data structures Book and Library to represent the XML data.
  • Parse XML Data: We use the XML-INTO opcode to parse the XML data into the Library data structure.
  • Display Parsed Data: We loop through the Library array and display the parsed data.
  • Generate XML Data: We use the XML-SAX opcode to generate XML data from the parsed data.

Conclusion

In this module, we learned how to handle XML data in RPG programming. We covered the basics of XML, how to parse XML data using the XML-INTO opcode, and how to generate XML data using the XML-SAX opcode. We also worked through practical examples and exercises to reinforce our understanding. In the next module, we will explore how to interface RPG with other programming languages.

© Copyright 2024. All rights reserved