0

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!

Community
  • 1
  • 1
user3790173
  • 45
  • 1
  • 6
  • I wonder if your XML might be corrupt. Should the Axmlns="" part really be something like xmlns:something=""? xmlns is a "xml namespace prefix". Remove Axlmns="" from your code and it basically works. – Jensd Jun 30 '14 at 13:59
  • Yes, I know that It'll work if I'll remove the attribute. The Axmlns is there for example, with real data it could be something like MessageType="type". Problem is so that I can't get any value while the attribute is there/ – user3790173 Jun 30 '14 at 15:18

2 Answers2

4

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.

  • Nice answer! You could/should add "SERIALIZE-HIDDEN" or XML-NODE-TYPE "HIDDEN" to the field "foo" just to mark it as hidden. Doesn't make any difference in this case but might do so if you decide to "WRITE-XML" as well. – Jensd Jul 01 '14 at 08:17
  • I t totally agree Jensd. Just forgot it :) – Arno van der Ende Jul 01 '14 at 08:40
  • Thanks! I have verison 10.2B and don't have a PARENT-ID-RELATION feature, but I did it in same way- One temp-table for one tag and it works. Tried it before, but instead of node-type "text" used node-type "Element". Thanks, It works! :) – user3790173 Jul 01 '14 at 12:02
  • Is there a way do do this in version 10.2B with multiple of same tag. – Jason Weh Apr 21 '16 at 03:53
0

To do this in version 10.x, below:

DEFINE TEMP-TABLE MessageDetails NO-UNDO XML-NODE-NAME "MessageDetails"
    FIELD c_recid               AS RECID XML-NODE-TYPE "Hidden".

DEFINE TEMP-TABLE MessageTypeCode NO-UNDO
    FIELD Axmlns                AS CHARACTER XML-NODE-TYPE "Attribute"
    FIELD ElementValue          AS CHARACTER XML-NODE-TYPE "Text"
    FIELD c_recid               AS RECID     XML-NODE-TYPE "Hidden".

DEFINE DATASET dsReceiverInfo XML-NODE-NAME 'ReceiverInfo'
    FOR  MessageDetails, MessageTypeCode
    DATA-RELATION dr1 FOR MessageDetails, MessageTypeCode 
                      RELATION-FIELDS(c_recid, c_recid) NESTED foreign-key-hidden.

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

FOR EACH MessageTypeCode:
    DISP MessageTypeCode.c_recid
         MessageTypeCode.Axmlns
         MessageTypeCode.ElementValue FORMAT "X(20)"
        WITH STREAM-IO WIDTH 300.
END.