Import XML into dataset

Posted by ssouthwe on 15-Nov-2016 16:07

I'm trying to figure out whether it's possible to use a dataset's read-xml() method to read in some XML automatically, or if this situation will be yet another "roll-your-own" solution.

Here's what the XML looks like:

<MainTable>

  <Field1/>

  <Field2/>

  <Field3/>

  <Subitems>

    <Subitem>...</Subitem>

    <Subitem>...</Subitem>

  </Subitems>

</MainTable>


The above is the XML format that I'm given.  I don't have a choice to make them change it to fit ABL constraints.

If I define temp-tables for MainTable and SubItem, I can get read-xml() to populate MainTable, but I can't get it to work for the SubItem temp-table unless I define a fake SubItems temp-table and define a data-relation between my real table and the fake one.

Is there a way to use xpath notation or something like that to give ABL the clue of how my child records are situated?

define temp-table tt-subitem
 xml-node-name "SubItems/SubItem"
...

 

All Replies

Posted by Brian K. Maher on 16-Nov-2016 03:48

Try reading the xml into a dynamic dataset where you have no tables defined and see what the results are.

Posted by Jean-Christophe Cardot on 16-Nov-2016 04:49

Try this. This loads the XML file into a dynamic dataset for which no temp-table has been defined, then outputs a txt file with the structure and contents of the generated temp-tables.

Good to know: READ-XML on a dataset handle will automatically create all the needed temp-tables and relations.

DEFINE VARIABLE hChildBuffer  AS HANDLE    NO-UNDO.
DEFINE VARIABLE hDataset      AS HANDLE    NO-UNDO.
DEFINE VARIABLE hParentBuffer AS HANDLE    NO-UNDO.
DEFINE VARIABLE hQuery        AS HANDLE    NO-UNDO.
DEFINE VARIABLE hRelation     AS HANDLE    NO-UNDO.
DEFINE VARIABLE hTopBuffer    AS HANDLE    NO-UNDO.
DEFINE VARIABLE i             AS INTEGER   NO-UNDO.
DEFINE VARIABLE j             AS INTEGER   NO-UNDO.
DEFINE VARIABLE lOK           AS LOGICAL   NO-UNDO.

CREATE DATASET hDataset.
lOK = hDataset:READ-XML("FILE", "C:\TEMP\myfile.xml", "EMPTY", "", NO).

hTopBuffer = hDataset:GET-TOP-BUFFER().

/* log the received data */
OUTPUT TO c:/temp/mydataset.log.

DO i = 1 TO hDataset:NUM-TOP-BUFFERS:
    hTopBuffer = hDataset:GET-TOP-BUFFER(i).
    IF VALID-HANDLE(hTopBuffer) THEN DO:
        IF hTopBuffer:TABLE-HANDLE:HAS-RECORDS THEN blkRecords: DO:
            CREATE QUERY hQuery.
            IF NOT hQuery:SET-BUFFERS(hTopBuffer) THEN
                LEAVE blkRecords.
            IF NOT hQuery:QUERY-PREPARE("FOR EACH " + hTopBuffer:NAME) THEN
                LEAVE blkRecords.
            IF NOT hQuery:QUERY-OPEN THEN
                LEAVE blkRecords.
            PUT UNFORMATTED SKIP(1) hTopBuffer:NAME " records:" SKIP "--------------------" SKIP.
            REPEAT:
                hQuery:GET-NEXT().
                IF hQuery:QUERY-OFF-END THEN LEAVE.
                PUT UNFORMATTED "- " hTopBuffer:NAME " record, recid: " hTopBuffer:RECID SKIP.
                DO j = 1 TO hTopBuffer:NUM-FIELDS:
                    PUT UNFORMATTED "  . " hTopBuffer:BUFFER-FIELD(j):NAME " = " (IF hTopBuffer:BUFFER-FIELD(j):BUFFER-VALUE = ? THEN "<?>" ELSE hTopBuffer:BUFFER-FIELD(j):BUFFER-VALUE) SKIP.
                END.
            END.
            hQuery:QUERY-CLOSE().
            DELETE OBJECT hQuery.
        END.
    END.
END.

PUT UNFORMATTED SKIP(1) "Relations between temp-tables:" SKIP.
DO i = 1 TO hDataset:NUM-RELATIONS:
    hRelation = hDataset:GET-RELATION(i).
    hParentBuffer = hRelation:PARENT-BUFFER.
    hChildBuffer = hRelation:CHILD-BUFFER.
    MESSAGE hParentBuffer:NAME "->" hChildBuffer:NAME. /* debug */
    PUT UNFORMATTED "* " hParentBuffer:NAME "->" hChildBuffer:NAME SKIP .
    DO j = 1 TO hChildBuffer:NUM-FIELDS:
        PUT UNFORMATTED "  - " hChildBuffer:BUFFER-FIELD(j):NAME " / " hChildBuffer:BUFFER-FIELD(j):DATA-TYPE SKIP .
    END.
END.

OUTPUT CLOSE.

Posted by Patrick Tingen on 22-Nov-2016 03:21

You might also want to check this post  from Mark Davies. He describes a way to generate a table structure to load the XML file. I have used it on more than one occasion and it works quite well.

This thread is closed