xmlprogress-4glopenedge

Progress 4GL: Reading from XML to Dataset


When I'm trying to read from XML to TempTables using the Dataset and READ-XML method it works okay. But the problem is so: If there is attribute in tag then it returns empty result instead of element value. Tried it in different ways, but didn't get any results.

I found that it works only if the attribute name is "xmlns" like in this case Reading XML file to Dataset in Progress-4gl.

Here is my code and XML.

<?xml version="1.0" encoding="ISO-8859-15"?>
<?xml-stylesheet type="text/xsl" href="Test.xsl"?>
<ReceiverInfo Version="2.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Test.xsd">
   <MessageDetails>
      <MessageTypeCode Axmlns="">RECEIVERINFO</MessageTypeCode>
   </MessageDetails>
   <MessageDetails>
      <MessageTypeCode Axmlns="">RECEIVERINFO2</MessageTypeCode>
   </MessageDetails>
</ReceiverInfo>

And code:

def var icount as int no-undo initial 0.

DEF TEMP-TABLE ReceiverInfo NO-UNDO
   FIELD foo AS LOG.

DEF TEMP-TABLE MessageDetails NO-UNDO
   FIELD MessageTypeCode as CHAR XML-NODE-TYPE "Element".

DEF DATASET data FOR ReceiverInfo, MessageDetails.

DATASET data:READ-XML("file", "/home/ars/temp/tofile.xml", "empty", ?, FALSE, ?, "IGNORE") NO-ERROR.

DO icount = 1 TO ERROR-STATUS:NUM-MESSAGES:
      DISP ERROR-STATUS:GET-MESSAGE(icount) format "x(50)".
END.

FOR EACH MessageDetails.
      DISP MessageDetails.MessageTypeCode format "x(40)".
END.

Thanks for help!


Solution

  • Since the attribute is a child of MessageTypeCode, MessageTypeCode should be a temp-table instead of a field. ReceiverInfo can be the DATASET. I prefer to use PARENT-ID-RELATION to link the parent (MessageDetails) and child (MessageTypeCode) temp-tables.

    DEFINE TEMP-TABLE MessageDetails NO-UNDO
        FIELD foo AS LOGICAL.
    
    DEFINE TEMP-TABLE MessageTypeCode NO-UNDO
        FIELD Axmlns               AS CHARACTER XML-NODE-TYPE "Attribute"
        FIELD ElementValue         AS CHARACTER XML-NODE-TYPE "Text"
        FIELD MessageDetails_recid AS RECID     XML-NODE-TYPE "Hidden".
    
    DEFINE DATASET ReceiverInfo
          FOR MessageDetails, MessageTypeCode
          PARENT-ID-RELATION tab1tab2 FOR MessageDetails, MessageTypeCode PARENT-ID-FIELD MessageDetails_recid.
    
    DATASET ReceiverInfo:READ-XML("file", "/home/ars/temp/tofile.xml", "empty", ?, FALSE, ?, "IGNORE") NO-ERROR.
    
    FOR EACH MessageTypeCode:
        DISP MessageTypeCode.ElementValue FORMAT "X(30)"
             MessageTypeCode.Axmlns      
             MessageTypeCode.MessageDetails_recid.
    END.
    

    You can use XML-NODE-TYPE "Text" to get the value of the MessageTypeCode.

    Note: Each table can contain only one TEXT field. When a table contains a TEXT field, it cannot contain ELEMENT fields; it can contain only ATTRIBUTE fields. A table that contains a TEXT field cannot be part of a nested data-relation.