XML parsing using SAX or OE read-xml

kkumarc

New Member

This is regarding parsing an XML using SAX parser or OE read-xml.

My objective: I might have a big xml with say 1000's of Hotel details in the form of XML. Each Hotel node would have child nodes with information like Hotel code, description, availability from date , to date etc. From this huge XML i would like to filter the contents based on user search. User might search for some date range so i need to filter out only those hotels which matches the availability dates.

I am struggling to find a sample code which can be used for reading these nodes. Also i am not sure if SAX is better or OE read-xml. Please advice.

regards
krishna
 

RealHeavyDude

Well-Known Member
The READ-XML function is only an option if your XML exactly matches the Temp-Table or ProDataSet you try to load it into. I was only successful when I created the XML with the WRITE-XML function of the Temp-Table of ProDataSet in the first place, and, AFAIK, this is the way they are meant to be used.

As soon as you are dealing with a big XML document the SAX parser is your best friend. The only alternative would be the DOM parser but it is only suitable for small XML documents and, IMHO, not so straightforward to work with. I don't like the DOM parser much and I never use it - but I don't want to start a religious war here ...

As of 10.1c the documentation that comes with the product contains a book "Working with XML" that explains how to use the SAX parser in the ABL.

Heavy Regards, RealHeavyDude.
 

Cringer

ProgressTalk.com Moderator
Staff member
I suppose an alternative would be to pass the user search parameters into an XSL to transform the data into a smaller set that's easier to manipulate?

Just throwing out the idea :)
 

KleineCuypie

New Member
There is a fine solution to find a tag in XML but you have to be sure the tag is not duplicated with the same name.
What I mean is that your xml may not contain:
<hotel>
<id>1</id>
</hotel>
<person>
<id>1</id>
</person>

because when you search ID it will find both (u can also check it with logicals otherwise).

If this is the case, let me know I'll try to help u ..
 

kkumarc

New Member
Thanks KleineCuypie. I think you can help here.
Our xml is like this
<hotels>
<hotel>
<name>AAA </name>
<description>DES </description>
<destination>ALX </destination>
</hotel>
<HotelAvailabilityInfo>
<AvailabilityCode>AV</AvailabilityCode>
<AvailabilityStatusDescription>Available</AvailabilityStatusDescription>
</HotelAvailabilityInfo>
</hotels>
 

KleineCuypie

New Member
You have 2 solutions, you can use a SAX reader or a Msxml.DomDocument (don't know if it's supported by every version I'm using 10.2b).

A little example by using a Msxml.DomDocument:

Code:
DEFINE VARIABLE chXmlDoc AS COM-HANDLE.     
DEFINE VARIABLE chXmlNodeList AS COM-HANDLE.
DEFINE VARIABLE strPath AS CHARACTER INIT "C:\xmlFile.xml"

CREATE "Msxml.DomDocument" chXmlDoc.

blnOk = chXmlDoc:LOAD(strPath). /*the path of the xml*/

chXmlNodeList = chXmlDoc:documentElement:childNodes.
RUN readNodeList(chXmlNodeList).

PROCEDURE readNodeList:
DEFINE INPUT PARAMETER chXmlNodeList AS COM-HANDLE NO-UNDO.
DEFINE VARIABLE chNewXmlNodeList AS COM-HANDLE NO-UNDO.
DEFINE VARIABLE chXmlNode AS COM-HANDLE NO-UNDO.
DEFINE VARIABLE chXmlNodeParent AS COM-HANDLE NO-UNDO.
DEFINE VARIABLE i AS INTEGER     NO-UNDO INIT 0.


DO WHILE i < chXmlNodeList:LENGTH:
    chXmlNode = chXmlNodeList:ITEM(i). 
    chXmlNodeParent = chXmlNode:ParentNode.



    /* If there are childNodes he will read the new list of this node */
    /* <tag>value</tag> still has childNodes (PROGRESS RULES) */
    /* If he enters value, there are no more childNodes */ <---- Don't know if you get this one.. <tag> will have 1 child (value) so he will run readNodeList again..
    IF chXmlNode:hasChildNodes() THEN DO:
        chNewXmlNodeList = chXmlNode:childNodes().
        RUN readNodeList(chNewXmlNodeList). /*like going deeper in a tree*/
    END.
    ELSE DO:
        IF chXmlNodeParent:BaseName = "[COLOR=#333333]AvailabilityStatusDescription" THEN DO: /*chXmlNodeParent because of the comment above <[/COLOR][COLOR=#333333]AvailabilityStatusDescription> is the parent of the value in it..[/COLOR][COLOR=#333333]*/
            IF chXmlNode:nodeValue = "Available" THEN RUN doThis. /*The content "Available" will be seen as the xmlNode itself*/
        END.[/COLOR]
    END.

END PROCEDURE.

This is a little example. It's quite complicated but when you get the point it's easy. Maybe sax reader will be easier but will need more explanation I guess.
Let me know if you need more info.

Maybe this can help you if you want to use Msxml Domdocument http://msdn.microsoft.com/en-us/library/aa468547.aspx

Grtz.
 

tamhas

ProgressTalk.com Sponsor
SAX is clearly the right solution in ABL. Sounds like an XPATH problem. There was a session a few years back, Paris Exchange, maybe, on using XPATH from DataDirect, but I have not heard of people using it from ABL.
 

kkumarc

New Member
KleineCuypie , we can't use DOM since the XML's could be huge. We are now trying to avoid XML and trying to use OOPS programming to better manage the objects.
 
Top