Resolved Example from Doc - error

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]
 

Attachments

  • i-sax2d.p
    1 KB · Views: 4

GregTomkins

Active Member
Where's the rest? This compiles, but it's just methods that are never called from here. I looked in your previous post and it doesn't interact with this code (that I can see).
 

Stefan

Well-Known Member
Works fine with your xml file (after your XML file is fixed to start with a < and end with </Customers>).

Note that if your XML file contains an element for which no corresponding field exists in your temp-table you will get the error you mention since there is no error trap in the StartElement procedure (hDBFld = hBuf:BUFFER-FIELD(qName).) That statement will error if there is no field with the current value of qName.

For simplicity's sake, you do not need to split the code in two - you can set the :HANDLER to THIS-PROCEDURE.
 

Tracy Hall

New Member
Hey Greg, I am sure how I posted it was kind of confusing. The upload box does not accept xml files. Thank you Stefan, I think my problem was that I forgot to save before I tried again and since the file was getting called by the first one, I would get an error because the changes were not saved.
 
Top