Link to home
Start Free TrialLog in
Avatar of cocosteel
cocosteel

asked on

XML reader using class structure

hi

i am quite new to vb and am hoping to build an application in vb6 that reads some xml content and then inserts it to a database.

i have partially written 2 classes:
CReport
CCustomer

the xml structure i have mirrors these classes:

<Report>
<ReportNumber>1</ReportNumber>
     <Customer>
     <Name>CocoSteel</Name>
     </Customer>
<ReportDate>21/11/2002</ReportDate>
</Report>


the CReport class does the following

1. loads the xml file into a DOM
2. sends the document element to the following LoadXML method:

Public Sub LoadXML(node As MSXML2.IXMLDOMNode)

Set node = node.childNodes(0)

Do While Not node Is Nothing

    Select Case LCase(node.NodeName)
   
    Case Is = "reportnumber"
    ReportDate = node.text  ' report date is a property

    Case Is = "customer"
    customer.Loadxml node   ' customer is an instanciated
                            'object of the Ccustomer                         ' class
     
    Case Is = "reportdate"
    ReportOrganisation = node.text  ' report organisation is a property

    End Select
   
    Set node = node.nextSibling
   
   Loop

in the customer class there would also be a loadxml method which would loop through the child elements of the customer node.

The problem this created was that when the loop in the Report class reached the "customer" element it jumps into the customer class and destroys the node object in the Report class.  Accordingly when the code finishes in the customer class and jumps back to the Report class i cannot use the node object for .next sibling and therfore cannot finish the loop in the Report class.

I wondered if i actually created a DOM tree within the classes and put the nodes into this. and then put the values into these and then read them from this tree.  BUT it seems like this will be replicating work.  
i already have the data in a DOM so why should i create another?

So my question is:
Is there any way of maintaing the Report node object whilst i move into the Customer class object.  If not can you recommend any approach to achieving the same result without excessive complexity.
things to consider are:

1. i would like to use a class structure rather than doing the whole thing in one form procedure.
2. i have already read the "XML Wrapper template; Transform XML documents into vb classes" article on MSDN http://msdn.microsoft.com/msdnmag/issues/01/01/XMLWrap/default.aspx  - this is very good but i dont think i want to create another DOM structure when i already have the data in one at the start of the Report class.
3. i have not added in the inserts to the db yet but will do this later once i have exposed the content.

thankyou very much.







Avatar of AzraSound
AzraSound
Flag of United States of America image

>>it jumps into the customer class and destroys the node object in the Report class


Explain "destroys".  If you debug your project and set a breakpoint at:

customer.Loadxml node

And when the code hits that point do a Shift + F8 to execute that line, then when it steps out of that function call, in the Immediate window do a:


?node Is Nothing

If that returns False, do a:

?node.Text

and see what it returns
Avatar of cocosteel
cocosteel

ASKER

AzraSound  thanks for responding

i followed your instructions and got a true.  

so as this meant the Reportnode was getting set to nothing. i  decided to continue to pass that Reportnode in to the CCustomer class loadnode method.  but then to declare a new node in CCustomer and and set this new node:

CustomerNode = ReportNode.childNodes(0)

then use the new node to loop round the second element.  and this has allowed me to continue using the reportnode when i went back to the Report class.  

re: >>it jumps into the customer class and destroys the node object in the Report class - i was confused about this because i thought that when scope went to another object all nodes were automatically set to nothing?  having now fixed this i dont think this is correct??

Well, I never saw your function in the CCustomer class, but I assume it had a similar loop...looping until the passed in Node was Nothing.  Thus, that is why when it returned back to the CReport class function, the node was nothing.  Your function is passing the node ByRef, that is, it is passing a pointer to the node so that in CCustomer, you are working with the same node object in memory.  If you pass it ByVal to CCustomer, you would not suffer from this problem, and it sounds like maybe that is the way you may wish to approach this.
so i can just declare and use one node? do you think that is a better way of doing it than creating another node in the CCustomer?
ASKER CERTIFIED SOLUTION
Avatar of AzraSound
AzraSound
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
an interesting program for u is Visual code generator, u can find it at http://www.liquid-technologies.com/

The program generates the classes for u, saves a lot of time

U can download a trail version there, u can use it only for 15 classes and 30 attributes, but i guess that is sufficient ?
If u go over that split the scheme and then manual add the together.
I've use the program and was positively surprised :)

Hope it helps
thanks, you got me thinking about what was actually happening!