Link to home
Start Free TrialLog in
Avatar of ramramcat
ramramcatFlag for United States of America

asked on

Export VFP table to XML

Hi:
I am updating a VFP-7 app. where keyed data needs to be exported to an XML document. I am completely new to XML and totally ignorant.
My client has provided a sample XML and "SCHEMA" files (there are 81 of them - one for each data-set (field?).
I created a DBF that contains fields named the same as in the sample XML. There are about 250 fields. I tried using CURSORTOXML but my resulting XML does not much look like the sample XML.  This is the statement:
  CURSORTOXML("DbfTable", (M_XMLFil), 1, 512)
As stated, this app. was done with VFP-7 using a framework and would not be too easy to upgrade,  however, if VFP-9 has superior tools for creating the XML, I could create a mini app. using VFP-9 just to create the XML.
Is there a "crash course" out there as I just don't get it - its like trying to learn Greek or something! Please help get me on the right track.
Thanks.
CAM
ASKER CERTIFIED SOLUTION
Avatar of Cyril Joudieh
Cyril Joudieh
Flag of Lebanon 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
81 schema files? You'd need 1 xsd schema for one xml file, not 81. Or are you talking about 81 schemas for 81 different datasets, and a dataset is not equivalent to a field, but to a set of data, eg even several tables. Eg those 81 schemas could be for 81 tables of a database or for 81 different compositions of data.

Also, in general an xsd schema is denoting the schema of an xml file, not necessarily of a (single) table or a set of tables.

You can't simply rely on cursortoxml, as that is of course rather rigid and has no parameter to use a schema for the xml generation, you just can export/create a (embedded) schema in the xml output via xmltocursor.

With VFP8 XMLAdapter was introduced and you can do more with that, eg add several tables and created nested xml with it, but in the end it might be best to output the xml via low level functions as Cyril suggests, as you have full control of what is output, then of course.

You can then use the xsd schema to verify your output validates against that schema, in the end and get feedback what is wrong with your xml generation, if the xml doesn't validate.

Bye, Olaf.
SOLUTION
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
Avatar of jrbbldr
jrbbldr

One thing I just noticed about the code that I posted above is that I missed putting in any record designating tag after the ENDFOR (I told you the code was not tested!!!)

Good Luck
It should be TTOC for 'T'

I would also do ALLTRIM(STR(cFldVal,10,2)) for 'N'
Avatar of ramramcat

ASKER

Thanks everyone - it looks like low-level functions are the way to go for this. In JRBBLDR's example above, it looks like the XML for each record (or is it the entire table?) would be written to one memvar with no line-feeds and then written out one time. I believe this is also true for FWRITE. Is this true - that the XML is one long string and only appears to have line-feeds, etc. when viewed/printed?
Thanks again.
You can add CHR(13)+CHR(10) to every line to make it look good.

You could also add CHR(9) to tab it out.
In JRBBLDR's example above, it looks like the XML for each record (or is it the entire table?) would be written to one memvar with no line-feeds and then written out one time.

As I indicated that code is a generalization of an approach, not necessarily 'finished' code.
You can add record separator tag, tabs, CrLF's and anything else, before you write out the string.

Depending on the number of records and field you might be able to get multiple records into the one memory variable before writing the value(s) out.  Or you could write out each individual record as it was completed.

Good Luck

OK, I started to create a file with a header and already get this error upon opening the file:

Invalid at the top level of the document. Error processing resource 'file:///J:/FEDPCR/Testfile.xml'. Line 1, Position 39
<?xml version="1.0" encoding="UTF-8"?>

This is the code:

M_Id = FCREATE('Testfile.xml')      &&Assigns FileHandle number to M_Id
cHeader1 = '<?xml version="1.0" encoding="UTF-8"?>' + CHR(13)+ ;
'  - <Header>'  +   CHR(13)+;
'    <D01_01>37-12345</D01_01>' +   CHR(13)+;
'    <D01_03>37</D01_03>' +   CHR(13)+;
'    <D01_04>37183</D01_04>' +   CHR(13)+;
'  - <Record>'
FWRITE((M_Id), cHeader1)
FCLOSE((M_Id))

Pos. 39 is a space (or carriage return) but without it everything is run - on.  What am I doing wrong? This is just the beginning header - have many data items to go......
Thanks.

First of all I would use this:

#DEFINE TAB CHR(9)
#DEFINE CRLF CHR(13)+CHR(10)

cXMLline = [<?xml version="1.0" encoding="Windows-1252" standalone="yes" ?>] + CRLF

I think the problem is that you are using -<. You should do <. The browser adds + or - to the tags.

SPACE is CHR(32).
I also use XML parsers, readers and writers using XMLDOC.

Here is how I start it.

TRY
      oXMLDoc = CREATEOBJECT("MSXML2.DomDocument")
CATCH
      lOK = .F.
      = MESSAGEBOX("Microsoft XML Parser is not installed on this machine. Please check with the administrator to install it from Microsoft Office CD-Pack.", 48, appname)
ENDTRY
IF NOT lOK
      RETURN
ENDIF
oThermometer = CREATEOBJECT('thermometer','Reading Map')
oXMLDoc.ValidateOnParse = .T.
oXMLDoc.Load(cFileMap)
DO WHILE oXMLDoc.readyState <> 4
      DOEVENTS
ENDDO
IF NOT oXMLDoc.Parsed
      = MESSAGEBOX("The XML is corrupted AND NOT parsed successfully!", 48, appname)
      RELEASE oXMLDoc
      lOK = .F.
      RETURN
ENDIF
oNodes = oXMLDoc.SelectNodes("//.")
The way that I test things is to write into the memory variable and then open some 'scratch' table with a Memo field.   Then I do a REPLACE MemoFld WITH cXMLString.- the memo field contents can then be examined.

After that I can view the XML string as it would be written to a text file.

Depending on how many records you are writing and how many fields are in each record, you MIGHT be able to get the entire XML string into a single memory variable before the Write.

Good Luck


SOLUTION
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
I think Notepad++ does that.
SOLUTION
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
Thank you ALL for your expertise - great solutions and learning experience!!
I have written out the entire XML using low-level functions and my client's "rules" and data using VFP's commands, logic and control of data. Works like a charm!