Tracy Hall
New Member
This bit of code is the second part of the example of SAX-PARSE an XML file to a temp-table. The original code used the connection to the Sports2000 db and defined the temp-table like customer. The objective I am working on I am importing an XML file to a temp-table for some further manipulation. I did not want to use that temp-table definition so I added my own. The original code that they supplied in the doc, worked for the first part but when it got to the part with the fields it said that the buffer-field did not exist or something like that. I tried to fix that, but I couldn't even fix that. You can imagine my confidence is not too good right now. I just want to see this work so I can figure out where I need to go from there. I will attach the first part and a block of the XML is at the very bottom of this post so you can look at it if you need to.
Code:
DEFINE VARIABLE hBuf AS HANDLE NO-UNDO.
DEFINE VARIABLE hDBFld AS HANDLE NO-UNDO.
/* Variable in which to accumulate all the text data for one element coming
in through potentially multiple calls (per element) to the Characters
procedure */
DEFINE VARIABLE currentFieldValue AS CHARACTER NO-UNDO.
/* Simple-minded state machine – the code makes minimal use of it, but it
could easily be used to validate the structure of the document in this
example. */
DEFINE VARIABLE iProcessingState AS INTEGER NO-UNDO.
DEFINE TEMP-TABLE ttCustomer
FIELD CustNum AS CHARACTER
FIELD Name AS CHARACTER
FIELD Country AS CHARACTER
FIELD Address AS CHARACTER
FIELD Address2 AS CHARACTER
FIELD City AS CHARACTER
FIELD State AS CHARACTER
FIELD Postal-Code AS CHARACTER
FIELD Contact AS CHARACTER
FIELD Phone AS CHARACTER
FIELD Sales-Rep AS CHARACTER
FIELD Credit-Limit AS CHARACTER
FIELD Balance AS CHARACTER
FIELD Terms AS CHARACTER
FIELD Discount AS CHARACTER
FIELD Comments AS CHARACTER.
&SCOPED-DEFINE READY-TO-START 1
&SCOPED-DEFINE GETTING-RECORDS 2
&SCOPED-DEFINE GETTING-FIELDS 3
&SCOPED-DEFINE DONE 4
hBuf = BUFFER ttCustomer:HANDLE.
PROCEDURE StartDocument:
iProcessingState = {&READY-TO-START}.
END PROCEDURE.
PROCEDURE StartElement:
DEFINE INPUT PARAMETER namespaceURI AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER localName AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER qName AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER attributes AS HANDLE NO-UNDO.
IF qName = "Customers" THEN
iProcessingState = {&GETTING-RECORDS}.
ELSE IF qName = "Customer" THEN DO:
/* Starting a new customer, so create the record */
CREATE ttCustomer.
ASSIGN
/* Get the fields that are in the XML doc as attributes */
ttCustomer.CustNum = attributes:GET-VALUE-BY-QNAME("CustNum")
ttCustomer.Name = attributes:GET-VALUE-BY-QNAME( "Name" )
iProcessingState = {&GETTING-FIELDS}.
END.
ELSE IF iProcessingState = {&GETTING-FIELDS} THEN DO:
/* Get a handle to the field whose name corresponds to the element name */
hDBFld = hBuf:BUFFER-FIELD(qName).
/* Re-init the variable in which we accumulate the field value */
currentFieldValue = "".
END.
END PROCEDURE.
PROCEDURE Characters:
DEFINE INPUT PARAMETER charData AS MEMPTR NO-UNDO.
DEFINE INPUT PARAMETER numChars AS INTEGER NO-UNDO.
/* Get the text value of the field (hDBFld was set to the correct field
in StartElement */
currentFieldValue = currentFieldValue + GET-STRING(charData, 1, GET-SIZE(charData)).
END PROCEDURE.
PROCEDURE EndElement:
DEFINE INPUT PARAMETER namespaceURI AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER localName AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER qName AS CHARACTER NO-UNDO.
IF localName = "Customers" THEN
iProcessingState = {&DONE}.
ELSE IF localName = "Customer" THEN
iProcessingState = {&GETTING-RECORDS}.
ELSE IF iProcessingState = {&GETTING-FIELDS} THEN
hDBFld:BUFFER-VALUE = currentFieldValue.
END PROCEDURE.
PROCEDURE EndDocument:
/* Show that data made it by displaying temp-table */
FOR EACH ttCustomer:
DISPLAY ttCustomer.Name.
END.
RUN Cleanup.
END PROCEDURE.
PROCEDURE FatalError:
DEFINE INPUT PARAMETER errMessage AS CHARACTER NO-UNDO.
/* Not necessary to do anything with PRIVATE-DATA, this is just an example
of what you could do */
SELF:PRIVATE-DATA = "FATAL".
RUN Cleanup.
/* RETURN ERROR in an error handler implicitly calls SELF:STOP-PARSING( ),
sets SELF:PARSE-STATUS to SAX-PARSER-ERROR, and raises the ABL ERROR
condition. */
RETURN ERROR errMessage
+ "(Line " + STRING(SELF:LOCATOR-LINE-NUMBER)
+ ", Col " + STRING(SELF:LOCATOR-COLUMN-NUMBER) + ")".
END PROCEDURE.
/* This is not a SAX callback; it is just a local utility */
PROCEDURE Cleanup:
/* In case we have parsed previous documents */
hBuf:EMPTY-TEMP-TABLE( ).
END.
**********************************XML FILE *****************************************
?xml version='1.0' ?>
<Customers>
<Customer Name="Lift Line Skiing" Cust-num="1">
<Country>USA</Country>
<Address>276 North Street</Address>
<Address2></Address2>
<City>Boston</City>
<State>MA</State>
<Postal-Code>02114</Postal-Code>
<Contact>Gloria Shepley</Contact>
<Phone>(617) 450-0087</Phone>
<Sales-Rep>HXM</Sales-Rep>
<Credit-Limit>66700</Credit-Limit>
<Balance>42568</Balance>
<Terms>Net30</Terms>
<Discount>35</Discount>
<Comments>This customer is on credit hold.</Comments>
</Customer>
[code]