Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

XML

Status
Not open for further replies.

FoxLearner

Programmer
Aug 29, 2002
93
US
Hi All

Can any one tell me how to generate a single XML document from multiple cursors? I need to call a webservice with the following examples of xml schema and xml document.
The schema is something like this:

***********************

<?xml version=&quot;1.0&quot; standalone=&quot;yes&quot;?>
<xs:schema id=&quot;NewDataSet&quot; xmlns=&quot;&quot; xmlns:xs=&quot; xmlns:msdata=&quot;urn:schemas-microsoft-com:xml-msdata&quot;>
<xs:element name=&quot;NewDataSet&quot; msdata:IsDataSet=&quot;true&quot;>
<xs:complexType>
<xs:choice maxOccurs=&quot;unbounded&quot;>
<xs:element name=&quot;OutputOptions&quot;>
<xs:complexType>
<xs:sequence>
<xs:element name=&quot;Cover&quot; type=&quot;xs:boolean&quot; minOccurs=&quot;0&quot; />
<xs:element name=&quot;UnderwriterInfo&quot; type=&quot;xs:boolean&quot; minOccurs=&quot;0&quot; /> .....
.....
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name=&quot;GroupInformation&quot;>
<xs:complexType>
<xs:sequence>
<xs:element name=&quot;Application&quot; type=&quot;xs:string&quot; minOccurs=&quot;0&quot; />
<xs:element name=&quot;UserName&quot; type=&quot;xs:string&quot; minOccurs=&quot;0&quot; />
.....
.....
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name=&quot;IndividualCensus&quot;>
<xs:complexType>
<xs:sequence>
<xs:element name=&quot;TierLevel&quot; type=&quot;xs:string&quot; minOccurs=&quot;0&quot; />
<xs:element name=&quot;Sex&quot; type=&quot;xs:string&quot; minOccurs=&quot;0&quot; />
....
....
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name=&quot;Plan1&quot;>
<xs:complexType>
<xs:sequence>
<xs:element name=&quot;RatingID&quot; type=&quot;xs:string&quot; minOccurs=&quot;0&quot; />
<xs:element name=&quot;OldRenewal&quot; type=&quot;xs:boolean&quot; minOccurs=&quot;0&quot; />
<xs:element name=&quot;CoinsuranceInNetwork&quot; type=&quot;xs:string&quot; minOccurs=&quot;0&quot; />
........
........
........
********************
Data comes from cursors curOutputOptions, curGroupInfo, curIndCensus, curPlan1,...

The XML Document looks something like this:

*********************
<?xml version=&quot;1.0&quot; standalone=&quot;yes&quot;?>
<NewDataSet>
<OutputOptions>
<Cover>true</Cover>
<UnderwriterInfo>true</UnderwriterInfo>
<AgeSexRateDetail>true</AgeSexRateDetail>
<AgeSexRateEmpContr>true</AgeSexRateEmpContr>
<Rates>true</Rates>
<Algorithm>false</Algorithm>
<AlgorithmDetail>false</AlgorithmDetail>
<LOB>false</LOB>
</OutputOptions>
<GroupInformation>
<Application>MarketingApp</Application>
<UserName>MJONSON1</UserName>
<UserType>TESTER</UserType>
.... .....
</GroupInformation>
<IndividualCensus>
<TierLevel>4</TierLevel>
<Sex>M</Sex>
<ContractType>EE</ContractType>
<CobraContract>false</CobraContract>
<MemberType>Emp</MemberType>
<ContractCode></ContractCode>
<Name>James Bond</Name>
<DateofBirth>1978-11-01</DateofBirth>
<Age>25</Age>
<Zip>72201</Zip>
</IndividualCensus>
<IndividualCensus>
<TierLevel>4</TierLevel>
<Sex>M</Sex> ....
.....

</IndividualCensus>
<PPOPlan>
<RatingID>MWRate0</RatingID>
<OldRenewal>false</OldRenewal>
<PlanSequence>0</PlanSequence>
....
....
***************************
I have the schema and cursors but don't know how to generate this type of XML document.
Will you please tell me /show me reference where I can learn this ASAP?

Thanks and Regards
FoxLearner
 
FoxLearner.

Pretty tricky stuff, but here is a sample of a DLL that I wrote recently that generates an XML base on two cursor. Don't pay attention to the code specific things but rather the structure of the code. (Sorry for the lenght of the code)
Code:
**************************************************
*-- Class Library:  d:\misroot\xml\xml.vcx
**************************************************


**************************************************
*-- Class:        xmlgen (d:\misroot\xml\xml.vcx)
*-- ParentClass:  custom
*-- BaseClass:    custom
*-- Time Stamp:   09/17/03 01:36:14 PM
*
DEFINE CLASS xmlgen AS custom OLEPUBLIC


	Height = 16
	Width = 100
	Name = &quot;xmlgen&quot;
	sfilename = .F.
	cfilename = .F.
	lcpath = .F.
	lctemp = .F.


	PROCEDURE xml1
		Lparameter cTableName
		Select(cTableName)
		Set Textmerge On Noshow
		Set Textmerge To (This.cFileName) Noshow
		           Select(cTableName)
		            \\<?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?>
		            \<<'<?xml-stylesheet type=&quot;text/xsl&quot; href=&quot;'+ THIS.sFileName +'&quot;?>'>>
		            \<?xml-stylesheet type=&quot;text/xsl&quot; href=&quot;suninvoice.xsl&quot;?>
		            \<<CHR(60)+ALIAS()+&quot;_table&quot;+CHR(62)>>
		Scan
		            \<<CHR(60)+ALIAS()+CHR(62)>>
			For iFields = 1 To Fcount()
				cField = Field(iFields)
		                    \<<&quot;    &quot;+CHR(60) + TRIM(cField)+CHR(62)+CHR(60)+&quot;![CDATA[&quot;>>
				m.mvalu = Iif(Vartype(&cField) = &quot;G&quot;, &quot;General Field&quot;, ;
					IIF(Vartype(&cField) = &quot;L&quot;, Iif(&cField, &quot;T&quot;, &quot;F&quot;), &cField))
		                    \\<<m.mvalu>>
		                    \\<<&quot;]]&quot;+CHR(62)+CHR(60)+&quot;/&quot;+TRIM(cField)+CHR(62)>>
			Next
		            \<<CHR(60)+&quot;/&quot;+ ALIAS()+CHR(62)>>
		Endscan
		            \<<CHR(60)+&quot;/&quot;+ ALIAS()+&quot;_table&quot;+CHR(62)>>
		           
		this.end()
		cTableName = &quot;detail1&quot;
		This.xsl1(cTableName)
	ENDPROC


	PROCEDURE xsl1
		*** This section creates the XSL document
		*** This particular stylesheet presents the data in a table format.
		Lparameter cTableName
			Strtofile(;
				&quot;<?xml version='1.0'?>&quot; +CR+;
				THIS.pTab(1)+&quot;<xsl:stylesheet xmlns:xsl='[URL unfurl="true"]http://www.w3.org/TR/WD-xsl'>&quot;[/URL] +CR+;
				THIS.pTab(2)+&quot;<xsl:template match='/'>&quot; +CR+;
				THIS.pTab(3)+&quot;<HTML>&quot; +CR+;
				THIS.pTab(3)+&quot;<HEAD>&quot;+CR+;
				THIS.pTab(3)+&quot;<TITLE>&quot;+Alias()+ &quot;</TITLE>&quot; +CR+;
				THIS.pTab(3)+&quot;<H2>&quot;+Alias()+ &quot; Information</H2>&quot; +CR+;
				THIS.pTab(3)+&quot;</HEAD>&quot;+CR+;
				THIS.pTab(4)+&quot;<BODY BGCOLOR = 'white'>&quot; +CR+;
				THIS.pTab(5)+&quot;<TABLE BORDER= '1' bgcolor='#FFFFF0'>&quot; +CR+;
				THIS.pTab(6)+&quot;<TR>&quot; +CR, This.sFileName)

			For iFields = 1 To Fcount()
				cField = Fields(iFields)
				Strtofile(This.pTab(6)+&quot;<TD><b>&quot;+ cField+ &quot;</b></TD>&quot; +CR, This.sFileName, lAdditive)
			Endfor iFields
			Strtofile(This.pTab(6)+&quot;</TR>&quot; +CR, This.sFileName, lAdditive)

			Strtofile(This.pTab(6) + &quot;<xsl:for-each select='&quot; + Alias() + &quot;_table/&quot; + Alias() + &quot;'>&quot; +;
				CR + This.pTab(6)+&quot;<TR>&quot;+CR, This.sFileName, lAdditive)

			For iFields = 1 To Fcount()
				cField = Fields(iFields)
				Strtofile(This.pTab(7)+&quot;<TD><xsl:value-of select='&quot;+ cField+ &quot;'/></TD>&quot;+CR, This.sFileName, lAdditive)
			Endfor iFields

			Strtofile(This.pTab(6)+&quot;</TR>&quot;+CR, This.sFileName, lAdditive)
			Strtofile(This.pTab(6)+&quot;</xsl:for-each>&quot;+CR+;
				THIS.pTab(5)+&quot;</TABLE>&quot;+CR+;
				THIS.pTab(4)+&quot;</BODY>&quot;+CR+;
				THIS.pTab(3)+&quot;</HTML>&quot;+CR+;
				THIS.pTab(2)+&quot;</xsl:template>&quot;+CR+;
				THIS.pTab(1)+&quot;</xsl:stylesheet>&quot;, This.sFileName, lAdditive)
			Return .T.
	ENDPROC


	PROCEDURE ptab
		Lparam nTab
		cTabString = &quot;&quot;
		For itab = 1 To nTab
			cTabString = cTab + cTabString
		Endfor
		Return cTabString
	ENDPROC


	PROCEDURE end
		LPARAMETERS lcAlias
		 \<<CHR(60)+&quot;/&quot;+ lcAlias+CHR(62)>>
		Set Textmerge To
		Set Textmerge Off
	ENDPROC


	PROCEDURE cursors
		Lparameters lcTablename,nIcid,lcPeriod
		This.superint()
		This.OpenTables()
		lcFileName = Alltrim(lcPeriod)+nIcid
		This.cFilename = Alltrim(lcFileName)+&quot;.xml&quot;
		This.sfilename = Alltrim(lcFileName)+&quot;.xsl&quot;
		This.cFilename = Alltrim(This.lctemp )+This.cFilename
		SET DATE long
		Local Y,x,a,b
		Y = 0
		a = 0
		b = 0
		x = 0
		Select client
		If Seek(nIcid,'client','coldcid')
			Store client.icid To lnIcid
		Endif
		Select *;
			FROM invoice;
			WHERE invoice.icid = lnIcid ;
			AND Substr(cinvono,1,7) =lcPeriod;
			INTO Cursor Header
		Create Cursor header1 (Name c(80))
		Select Header
		Insert Into header1 (Name) Values (nIcid)
		Insert Into header1 (Name) Values (Dtoc(Header.billdate))
		Insert Into header1 (Name) Values (Header.cinvono)
		Insert Into header1 (Name) Values (Dtoc(Header.billdate+14))
		Insert Into header1 (Name) Values (Header.fname+&quot; &quot;+Header.lname)
		Insert Into header1 (Name) Values (client.cstreetno+&quot; &quot;+client.cstreet )
		Insert Into header1 (Name) Values (Alltrim(client.ccity)+&quot;, &quot;+ client.cprovince+ &quot; &quot;+client.cpostcode)
		Insert Into header1 (Name) Values (Transform(Header.prevbal,'@99,999.99'))
		Insert Into header1 (Name) Values (Transform(-Header.payments,'@99,999.99'))
		Insert Into header1 (Name) Values (Transform(Header.Other+Header.credit,'@99,999.99'))
		Insert Into header1 (Name) Values (Transform(Header.toll,'@9,999,999.99'))
		Insert Into header1 (Name) Values (Transform(Header.interest,'@9,999,999.99'))
		Insert Into header1 (Name) Values (Transform(Header.Other,'@9,999,999.99'))
		Insert Into header1 (Name) Values (Transform(Header.othertax1,'@9,999,999.99'))
		Insert Into header1 (Name) Values (Transform(Header.tax1,'@9,999,999.99'))
		Insert Into header1 (Name) Values (Transform(Header.tax2,'@9,999,999.99'))
		Insert Into header1 (Name) Values (Transform(Header.newbalance,'@9,999,999.99'))
		Select Distinct cService  From lftDetail Where icid = lnIcid And Substr(cinvono,1,7)=lcPeriod Into Cursor grouping
		x = Reccount()
		If x > 0
		    SELECT header1
			This.xml2(&quot;header1&quot;)
			This.xml6(&quot;Header&quot;)
		Endif
		Select grouping
		Go Top
		If !Eof()
			Do While Y < x
				a = 0
				b = 0
				lcDesc = ''
				lcServ = grouping.cService
				Select Date,cTime,cTerm_ph,cTerm_pl,nDur,Transform(nDur,'999.99') As nDur,(Iif(cService=&quot;E&quot;,&quot;Equal_Access&quot;,Iif(cService=&quot;8&quot;,&quot;Tool_Free&quot;,&quot;Calling_Card&quot;)));
					AS service From lftDetail Where Substr(cinvono,1,7)=lcPeriod And icid = lnIcid And cService= lcServ  Into Cursor header12
				Store header12.service To lcDesc
				lcDesc = Alltrim(lcDesc)
				This.xml5(lcDesc)
				Select Distinct cani From lftDetail Where icid = lnIcid And Substr(cinvono,1,7)=lcPeriod And cService = lcServ Into Cursor group2
				a = Reccount()
				Do While b < a
					lcAni=''
					lcAni = Alltrim(cani)
					Select Date,cTime,cTerm_ph,cTerm_pl,Transform(nDur/60,'9999.99') As nDur,Transform(nCharge,'@$$$,$$$.$$') As nCharge ;
						FROM lftDetail Where Substr(cinvono,1,7)=lcPeriod And icid = lnIcid And cani = lcAni Into Cursor header12
					This.xml5(&quot;Ani&quot;)
					This.xml7(&quot;No&quot;,lcAni)
					This.xml4(&quot;header12&quot;,&quot;header&quot;,&quot;&quot;)
					b = b + 1
					This.xml6(&quot;Ani&quot;)
					Select group2
					Skip
				Enddo
				Y = Y + 1
				This.xml6(lcDesc)
				Select grouping
				Skip
			Enddo

			This.End(&quot;MainInvoice&quot;)
		Else
		Endif
	ENDPROC


	PROCEDURE xml2
		Lparameter cTableName
		LOCAL a 
		a = 1
		Set Textmerge On Noshow
		Set Textmerge To (This.cFileName) Noshow
		            \\<?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?>
		             \<?xml-stylesheet type=&quot;text/xsl&quot; href=&quot;suninvoice.xsl&quot;?>
		            \<<CHR(60)+&quot;MainInvoice&quot;+CHR(62)>>
		This.xml8(&quot;Header&quot;)
		Select(cTableName)
		Scan
		            \<<CHR(60)+ALIAS()+ALLTRIM(STR(a))+CHR(62)>>
			For iFields = 1 To Fcount()
				cField = Field(iFields)
		                    \<<&quot;    &quot;+CHR(60) + TRIM(cField)+CHR(62)+CHR(60)+&quot;![CDATA[&quot;>>
				m.mvalu = Iif(Vartype(&cField) = &quot;G&quot;, &quot;General Field&quot;, ;
					IIF(Vartype(&cField) = &quot;L&quot;, Iif(&cField, &quot;T&quot;, &quot;F&quot;), &cField))
				m.mvalu = Alltrim(m.mvalu)
		                    \\<<m.mvalu>>
		                    \\<<&quot;]]&quot;+CHR(62)+CHR(60)+&quot;/&quot;+TRIM(cField)+CHR(62)>>
			Next
		            \<<CHR(60)+&quot;/&quot;+ ALIAS()+ALLTRIM(STR(a))+CHR(62)>>
		   a = a + 1
		Endscan
	ENDPROC


	PROCEDURE xml3
		Lparameter cTableName,lcAlias,cGroup
		Select(cTableName)
		FSEEK(this.cfilename, 0, 2)
		 \<<CHR(60)+cGroup+CHR(62)>>
		Scan
		      
			For iFields = 1 To Fcount()
				cField = Field(iFields)
		                    \<<&quot;    &quot;+CHR(60) + TRIM(cField)+CHR(62)+CHR(60)+&quot;![CDATA[&quot;>>
				m.mvalu = Iif(Vartype(&cField) = &quot;G&quot;, &quot;General Field&quot;, ;
					IIF(Vartype(&cField) = &quot;L&quot;, Iif(&cField, &quot;T&quot;, &quot;F&quot;), &cField))
					m.mvalu = ALLTRIM(m.mvalue)
		                    \\<<m.mvalu>>
		                    \\<<&quot;]]&quot;+CHR(62)+CHR(60)+&quot;/&quot;+TRIM(cField)+CHR(62)>>
			Next
		            
		            
		Endscan

		          
	ENDPROC


	*-- Programmatically opens the tables and views associated with the data environment.
	PROCEDURE opentables

		USE CURDIR()+&quot;\clients\client.dbf&quot; shared again IN 0
		USE CURDIR()+&quot;\2003080\lftdetail.dbf&quot; SHARED AGAIN IN 0
		USE CURDIR()+&quot;\2003080\invoice.dbf&quot; SHARED AGAIN IN 0
	ENDPROC


	PROCEDURE xml4
		LPARAMETER cTableName,lcAlias,cGroup
		SELECT(cTableName)
		FSEEK(THIS.cfilename, 0, 2)
		IF !EMPTY(cGroup)
		 \<<CHR(60)+cGroup+CHR(62)>>
		ENDIF
		SCAN
		       \<<CHR(60)+&quot;ROW&quot;+CHR(62)>>
		   FOR iFields = 1 TO FCOUNT()
		      cField = FIELD(iFields)
		                    \<<&quot;    &quot;+CHR(60) + TRIM(cField)+CHR(62)+CHR(60)+&quot;![CDATA[&quot;>>
		      m.mvalu = IIF(VARTYPE(&cField) = &quot;G&quot;, &quot;General Field&quot;, ;
		         IIF(VARTYPE(&cField) = &quot;L&quot;, IIF(&cField, &quot;T&quot;, &quot;F&quot;), &cField))
		      m.mvalu = ALLTRIM(m.mvalu)
		                    \\<<m.mvalu>>
		                    \\<<&quot;]]&quot;+CHR(62)+CHR(60)+&quot;/&quot;+TRIM(cField)+CHR(62)>>

		   NEXT
		       \<<CHR(60)+&quot;/ROW&quot;+CHR(62)>>

		ENDSCAN
	ENDPROC


	PROCEDURE xml5
		lparameter lcService
		FSEEK(this.cfilename, 0, 2)
		    \<<CHR(60)+lcService+CHR(62)>>
	ENDPROC


	PROCEDURE xml6
		lparameter lcService
		FSEEK(this.cfilename, 0, 2)
		 \<<CHR(60)+&quot;/&quot;+lcService+CHR(62)>>
	ENDPROC


	PROCEDURE xml7
		lparameter lcvalue,lcAni
		m.mvalu = lcAni
		FSEEK(this.cfilename, 0, 2)
		 \<<CHR(60)+(lcValue)+CHR(62)>><<m.mvalu>><<CHR(60)+&quot;/&quot;+(lcValue)+CHR(62)>>
		    
	ENDPROC


	PROCEDURE superint
		SET SAFETY off
		SET DATE long
		SET DATE mdy
		LOCAL lcPath,lcTemp,lcBuffer
		PUBLIC lAdditive
		PUBLIC CR
		PUBLIC cTab
		PUBLIC vfpYesNo
		DECLARE INTEGER GetPrivateProfileString IN Kernel32 ;
		   STRING, STRING, STRING, STRING @, INTEGER, STRING
		lcBuffer = SPACE(255)
		lcPath=GetPrivateProfileString( &quot;PATHS&quot;,&quot;lcCurrentDir&quot;,&quot;&quot;,@lcBuffer, LEN(lcBuffer), ADDBS(FULLPATH(CURDIR()))+&quot;SETUP.ini&quot;)
		lcBuffer = STRTRAN(lcBuffer,CHR(0),&quot;&quot;)
		lcBuffer = ALLTRIM(lcBuffer)
		THIS.lcPath = lcBuffer
		lcBuffer = SPACE(255)
		lcPath=GetPrivateProfileString( &quot;PATHS&quot;,&quot;lcXMLTempDir&quot;,&quot;&quot;,@lcBuffer, LEN(lcBuffer), ADDBS(FULLPATH(CURDIR()))+&quot;setup.ini&quot;)
		lcBuffer = STRTRAN(lcBuffer,CHR(0),&quot;&quot;)
		lcBuffer = ALLTRIM(lcBuffer)
		THIS.lcTemp = lcBuffer
		lAdditive= .T.
		cTab  =   CHR(9)
		CR =      CHR(10)
		vfpYesNo = 4
	ENDPROC


	PROCEDURE xml8
		LPARAMETERS lcService
		    \<<CHR(60)+lcService+CHR(62)>>
	ENDPROC


ENDDEFINE
*
*-- EndDefine: xmlgen
**************************************************


Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Mike
Thanks a lot. But could you please tell me just in a line or two, what all these procedures are doing? It is really confusing.
Thanks and Regards
FoxLearner
 
FoxLearner

Sure. But you have to understand that this DLL was designed to accomodate up to 4 cursors.
[ol][li]The first procedure to be called is Cursors (Which calls a method at the second line superint that sets up the environment, ie. files path etc...stored in a ini file, since this dll might be called from different computers) where I send the names of the name if the table (that will form the hearder cursor), along with the client we are dealing with and the &quot;billing period&quot;. You will notice that at some point during this function I switch tables (grouping), wich is the detailed part of the invoice. [/li]
[li]At the bottom of that function it calls anothe method (XML2()) that starts creating that textfile (XML), the header part that applies to all XML files. [/li]
[li]From there it calls the different methods that will format the data in the way I need it.[/li][/ol]

P.S. If you need to format your data in a specific way, just treat the functions the same way as you would in VFP, it just the result is out-puted in a textfile.


Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Mike
Thanks a lot for your time and help. I just got VFP8.0. After looking briefly, I got an idea. Let me know what you think whether feasible or not.
How about using the XMLAdapter object and use the table collection to assign the cursor and then use toXML() method to get the XML files?
What I mean is something like this:
oXMLAdapter.tables(1).name = &quot;curOutputOptins&quot;
oXMLAdapter.tables(2).name = &quot;curGroupInfo&quot;
oXMLAdapter.tables(3).name = &quot;curIndCensus&quot;
.....
.....
(Should it be oXMLAdapter.tables(1).alias = &quot;curOutputOptions&quot; ?)
And use oXMLAdapter.ToXML(&quot;c:\xmldir\xmldata.xml&quot;,,.t.)

Is it possible? (I am just 3 days in to this VFP 8.0.)
Thanks and Regards
FoxLearner
 
Thanks a lot for your time and help. I just got VFP8.0. After looking briefly, I got an idea. Let me know what you think whether feasible or not.

I'm sorry, I haven't used XMLAdapter, as I'm told that the XML format generated by that function might be limited to be used within VFP (I was told that Crystal Reports does like them), so I decided to avoid it and creae my own.


Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top