Answered Reading XML to ProDataset

Potish

Member
I need to consume an XML from a supplier using a ProDataset but have run into a problem due to how the suppliers sends some repeating information. There is section on the XML where data is passed as follows

<fare>
<class>First</class>
<basefare>1000.00</basefare>
<taxes>80.00</taxes>
<class>Business</class>
<basefare>500.00</basefare>
<taxes>80.00</taxes>
<class>Economy</class>
<basefare>250.00</basefare>
<taxes>80.00</taxes>
</fare>

Is it possible to define a ProDataset that can handle this XML? Each time a new <class> tag is read it would create a new row in a fare temp-table so the example above would have 3 rows. Supplier sends XML to many other subscribers so they cannot modify it for us.
 

Bounty

New Member
Im am pretty sure this is not possible (I had a similar issue). You can define the fields "class", "basefare" and "taxes" as EXTENT 3, but OpenEdge expects them to appear in the following order in the XML file:
<class>
<class>
<class>
<basefare>
<basefare>
<basefare>
<taxes>
<taxes>
<taxes>
 

Potish

Member
Im am pretty sure this is not possible (I had a similar issue). You can define the fields "class", "basefare" and "taxes" as EXTENT 3, but OpenEdge expects them to appear in the following order in the XML file:
<class>
<class>
<class>
<basefare>
<basefare>
<basefare>
<taxes>
<taxes>
<taxes>
Thank you for the response. So how did you end up handling your XML with similar issue?
 

Bounty

New Member
Because I only need one of the fields, I created a table with only that particular field.
In your case you could do something like the following and then combine the tables.
Code:
DEFINE TEMP-TABLE Fare1 SERIALIZE-NAME "fare"
  FIELD class AS CHARACTER EXTENT 3.
DEFINE DATASET dsFare1 FOR Fare1.

DEFINE TEMP-TABLE Fare2 SERIALIZE-NAME "fare"
  FIELD basefare AS DECIMAL EXTENT 3.
DEFINE DATASET dsFare2 FOR Fare2.
 
DEFINE TEMP-TABLE Fare3 SERIALIZE-NAME "fare"
  FIELD taxes AS DECIMAL EXTENT 3.
DEFINE DATASET dsFare3 FOR Fare3.
 
DATASET dsFare1:READ-XML("FILE", "fare.xml", "EMPTY", ?, ?).
DATASET dsFare2:READ-XML("FILE", "fare.xml", "EMPTY", ?, ?).
DATASET dsFare3:READ-XML("FILE", "fare.xml", "EMPTY", ?, ?).
The data in your example is in the three tables now. May this gets you started.
 

TomBascom

Curmudgeon
FWIW I find it helpful to approach many XML problems backwards. First define my TT and WRITE it to see what Progress is expecting:
Code:
define temp-table fare no-undo
  field class as character
  field basefare as decimal
  field taxes as decimal
.

create fare.
assign
  class    = "First"
  basefare = 1000.00
  taxes    = 80.00
.

create fare.
assign
  class    = "Business"
  basefare = 500.00
  taxes    = 80.00
.

create fare.
assign
  class    = "Economy"
  basefare = 250.00
  taxes    = 80.00
.

temp-table fare:write-xml( "file", "fare.xml", true ).

<?xml version="1.0"?>
<fare xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <fareRow>
    <class>First</class>
    <basefare>1000.0</basefare>
    <taxes>80.0</taxes>
  </fareRow>
  <fareRow>
    <class>Business</class>
    <basefare>500.0</basefare>
    <taxes>80.0</taxes>
  </fareRow>
  <fareRow>
    <class>Economy</class>
    <basefare>250.0</basefare>
    <taxes>80.0</taxes>
  </fareRow>
</fare>

So in this case it is easy to see the problem -- Progress expects "row" elements to surround the fields. To fix that I would use the SAX reader and build the desired TT element by element. Basically create a new row every time you see a new "<class>". That is a bit fragile in that you are assuming the element order will be uniform but that might be a relatively small risk.
 
Top