Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
XMLAdapter, XMLTable, XMLField
Message
From
08/11/2002 17:56:16
 
 
To
07/11/2002 11:53:14
General information
Forum:
Visual FoxPro
Category:
Other
Miscellaneous
Thread ID:
00719884
Message ID:
00720553
Views:
14
Hi Jim.

>Wanting to get further into their details I went to the Help Index, but none of them are listed.

Here's a (fairly long) sample program that shows how XMNLAdapter can be used to load XML, create a cursor, generate a diffgram from changes made in the cursor, and then use the diffgram to update local VFP tables. There's also a good sample that comes with VFP 8 (see the Solution Samples pane in the Task Pane and look for the VFP/VB.NET Web Service Samples sample). Unfortunately, it relies on Web Services, so if you don't have IIS, you can't try it out. That's why my example just simulates a Web Service.

Doug
local loWebService, ;
	lcXML, ;
	loXMLAdapter as XMLAdapter
close databases all
set multilocks on

* Simulate calling a Web Service to get some data.

loWebService = createobject('WebService')
lcXML = loWebService.GetCustomerByID('ALFKI')

* Create a cursor from the retrieved XML.

loXMLAdapter = createobject('XMLAdapter')
loXMLAdapter.LoadXML(lcXML)
loXMLAdapter.Tables.Item(1).ToCursor(.F., 'Customers')

* Make any changes desired.

select Customers
cursorsetprop('Buffering', 5)
messagebox("Here's the ALFKI customer retrieved from a simulated Web " + ;
	'Service. Make whatever changes you wish (you can even add or delete ' + ;
	'records), then press Ctrl+W to close the BROWSE window and save the ' + ;
	'changes back to the Web Service. ' + chr(13) + chr(13) + ;
	'Try blanking the CUST_ID or COMPANY fields, changing COUNTRY to ' + ;
	'"Canada", or adding a record with the same CUST_ID as an existing ' + ;
	'record (try "BERGS", for example) and see what happens when you save.', ;
	0, 'XMLAdapter Example')
browse

* Now write changes back to the Web Service if there are any.

if getnextmodified(0) <> 0

* We need to handle blank non-character fields (see comments in the CleanData
* procedure below).

	do CleanData

* Clean out the XMLAdapter first.

	with loXMLAdapter
		.ReleaseXML(.T.)
		.Tables.Remove(-1)

* Attach the Customers cursor to it.

		.AddTableSchema('Customers')

* Set some properties and flags for the ToXML method, then generate a diffgram
* from the cursor.

		.UTF8Encoded     = .T.		&& cursor contains international characters
		.IsDiffgram      = .T.		&& Generate an XML DiffGram	
		lcSchemaLocation = ''		&& Our schema is inline
		llIsFile         = .F.		&& Our XML is a stream 	
		llIncludeBefore  = .T.		&& Include <diffgram:before> format
		llChangesOnly    = .T.		&& Generate only changes we made
		.ToXML('lcXML', lcSchemaLocation, llIsFile, llIncludeBefore, ;
			llChangesOnly)
	endwith

* Display the diffgram.

	strtofile(lcXML,'Test.txt')
	messagebox("Here's the diffgram the XMLAdapter created that'll be " + ;
		'sent back to the Web Service to update the data source.', 0, ;
		'XMLAdapter Example')
	modify file Test.txt
	erase Test.txt

* Send the diffgram to the Web Service and display the results.

	lcResults = loWebService.UpdateCustomer(lcXML)
	if empty(lcResults)
		messagebox('The Web Service indicated that the update was ' + ;
			'successful.', 0, 'XMLAdapter Example')
	else
		messagebox('The Web Service indicated that the update was ' + ;
			'unsuccessful. The message from the Web Service is:' + chr(13) + ;
			chr(13) + lcResults, 0, 'XMLAdapter Example')
	endif empty(lcResults)
endif getnextmodified(0) <> 0
close databases all

* Because of the way VFP works, fields in a new record are "blank" rather than
* containing the proper "empty" value for their data type. This will cause an
* error when the XMLAdapter in the Web Service tries to load the XML because
* non-character fields will have an invalid value. 

procedure CleanData
local laFields[1], ;
	lnFields, ;
	lnI, ;
	lcField, ;
	lcType
lnFields = afields(laFields)
scan
	for lnI = 1 to lnFields
		lcField = laFields[lnI, 1]
		lcType  = laFields[lnI, 2]
		do case
			case not isblank(&lcField)
			case lcType = 'L'
				replace (lcField) with .F.
			case lcType $ 'NFIBY'
				replace (lcField) with 0
			case lcType $ 'DT'
				replace (lcField) with {}
		endcase
	next lnI
endscan
return

* This class simulates a Web Service: it both returns a customer record as XML
* and accepts a diffgram to make changes to the data.

define class WebService as Session
	procedure Init
		set multilocks on
		open database (_samples + 'Data\TestData')
	endproc
	procedure Destroy
		close database
	endproc

* Get the customer record for the specified ID and return it as XML.

	procedure GetCustomerByID(CustomerID as String) as String
		local lcXML
		select * from Customer where Cust_ID = ?CustomerID into cursor _Temp
		cursortoxml('_Temp', 'lcXML', 1, 0, 0, '1')
		use
		use in Customer
		return lcXML
	endproc

* Accept a diffgram and try to apply it to the Customer table.

	procedure UpdateCustomer(DiffGram as String) as String
		local lcMessage, ;
			loXMLAdapter as XMLAdapter, ;
			laError[1], ;
			loException as Exception

* First load the diffgram into an XMLAdapter. Then, create a cursor from the
* diffgram so we can do some business rules.

		lcMessage    = ''
		loXMLAdapter = createobject('XMLAdapter')
		try
			loXMLAdapter.LoadXML(DiffGram)
			loXMLAdapter.Tables.Item(1).ToCursor(.F., '_Temp')
			select _Temp
			do case
				case empty(nvl(Cust_ID, ''))
					throw 'Customer ID cannot be blank or null.'
				case empty(nvl(Company, ''))
					throw 'Company name cannot be blank or null.'
				case upper(Country) = 'CANADA'
					throw "We don't want no stinking Canadians!"
			endcase
			use
			
* Try to make the changes in the Customer table.

			use Customer
			cursorsetprop('Buffering', 5)
			begin transaction
			loXMLAdapter.Tables.Item(1).ApplyDiffgram('Customer')
			if not tableupdate(.T.)
				aerror(laError)
				throw laError[2]
			endif not tableupdate(.T.)
			end transaction
			messagebox('This is what the Customer table looks like after ' + ;
				'the diffgram was applied.', 0, 'Simulated Web Service')
			browse

* If an error occurred (either a VFP error or one we raised), rollback the
* transaction if we have one and get the error message to return.

		catch to loException
			if txnlevel() > 0
				rollback
			endif txnlevel() > 0
			if loException.ErrorNo = 2071
				lcMessage = loException.UserValue
			else
				lcMessage = loException.Message
			endif loException.ErrorNo = 2071

* Close any tables we opened.

		finally
			use in select('_Temp')
			use in select('Customer')
		endtry
		return lcMessage
	endproc
enddefine
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform