Wiki Home

Ragged XML Processing In VFP


Namespace: WIN_COM_API
"Ragged XML" might not be the right term - anyone know what might be? For XML such as the Small and Medium Business Meta Data proposal at http://www.smbmeta.org where a small/medium business can have a business card / directory entry on the website of the format:

«smbmeta version="0.1"»
	«business domain="tedroche.com"»
		«name»Ted Roche & Associates, LLC«/name»
		«description language="en"»
		Consultants specializing in Visual FoxPro, XML, SQL Server, SourceSafe and Open Source solutions.
		«/description»
		«type naics="541511"»Custom software design and development.«/type»
		«websiteDomain»www .tedroche.com«/websiteDomain»
		«lastUpdated»Wed, 19 Feb 2003 14:01:01 EST«/lastUpdated»
		«refreshDays»30«/refreshDays»
		«generator»SMBmeta.org File Creation Utility v1.0d«/generator»
		«docs»htt p://ww w.smbmeta.org/docs«/docs»
		«location country="us" postalCode="032293103" main="yes"»
			«about»Contoocook, NH«/about»
			«address»278 Kearsarge Avenue«/address»
			«serviceRange area="international"»International«/serviceRange»
			«languageSpoken language="en"/»
			«parking»None«/parking»
			«publicTransportation»None«/publicTransportation»
		«/location»
	«/business»
«/smbmeta»


(I see and I've kluged around the wiki display bug above-- Steven Black)

This XML document (the less-than and greater-than signs were substituted for ease of processing within the Wiki) has both attribute- and element-based properties, and embedded objects within objects. I could see where it would be convenient to represent this in VFP as an SMBMeta container object, a business container object and a location object contained within the business.

What's the optimal way to parse an existing XML stream into such an object and generate the XML from an object? How can you validate it? How can you ensure that invalid characters do not appear in the XML?
Ted - I've got some ideas on how to do this, but do you need the ability to handle repetition of elements? For example multiple location records being found in the above XML. Would a collection be needed in all cases, even the degenerate case of a single element being in the collection? This could greatly obfuscate simpler XMLObjects.

Isn't the XMLDOM validation enough to say whether the document is valid and doesn't contain invalid characters.

This document shows one problem with just being able to use generic VFP objects as a store for XML because some of the elements have case-sensitive names (websiteDomain). -- df
Probably the easiest way to handle the XML is to simply use the MSXML ActiveX objects, which will handle all the parsing for you, and won't have all the unnecessary properites (height, top, etc) that a Container will introduce. VFP8's Empty Class will make it possible to replicate the neat-object's in VFP, but in MSXML it's all done for you:
oX=CreateObject('msxml2.DOMDocument.4.0')
xx=[]
xx=FileToStr("XMLFILE.XML")
oX.LoadXML(xx)
oNode = oX.selectSingleNode("//one/two")
?oNode.NodeName
oNode = oX.selectSingleNode("//submeta/business/*")

This works with the simple xml in the example above, but I couldn't get it
Except that it's a real PITA to access the data content from the XMLDOM. Converting the XML data into a native VFP object makes working with the data a lot easier. -- df
I've had good experience creating VFP object societies, with containership-nesting matching exactly the XML element nesting, and with properties thereon for storing the XML properties. These objects have behavior that enforce the semantics of the XML DTD or Schema we're using, and objects know how to render, nest, fetch, and store themselves. It's slick as hell, but it's definitely not light reading. At heart it's a modified Web Connect ObjectToXML() with all the behavior and semantics found in the FFC _HTML.VCX classes. The DOM is definitely a useful piece for doing, at minimum, the transforms.-- Steven Black
In the case above, the organization has yet to produce a DTD or Schema, so that DOM objects that expect one to validate a document will not work, unless I go to the trouble of generating one. Is it worth the effort, or should I create a matching object model and have each object "emit" the appropriate XML fragments? -- Ted Roche

Well the DTD or Schema is what guides the object design: it specifies the precise case-sensitive name of attributes and elements, the rules of containership, as well as the cardinality, and whether items are required or not, and so on. So without a DTD/Schema you'd be guessing in the fog, no?-- Steven Black

There's a spec (specification or speculation, your choice) at http://www.trellixtech.com/smbmetaspec09proposal.html that dictates how I would set up a basic object model: optional and mandatory properties, attributes and collections of sub-items. I *thought* that XMLDOM required a schema or DTD to allow creation of the object. Perhaps it only needs it for validation? Is there a simple set of tutorials somewhere on how to create an XML document via the DOM? Up until now, I've gotten away with Cursor To XML or hand-assembly, but I think this process should be automated. Interesting link here about XML processors just hacking the strings: http://weblog.infoworld.com/udell/2003/03/18.html#a642 -- Ted Roche

The XMLDOM does *not* require a DTD or schema, necessarily. It just needs valid XML. That said, if you feed it a DTD or Schema as part of the XML, it will use it and barf if it doesn't validate, but it's not required per se.....-- Steven Black
Can anyone point to a simple code example that creates an XML document, adds attributes, elements and nodes? -- Ted Roche

Here's some code from one of my apps that sends multiple tables (Cursor To Xml()ed) in one XML document:

loXml = newobject('msxml2.domdocument')
loXml.async = .f.
loDocument = loXml.createElement('straightpo')

* Put the tables into CDATA sections of
* one XML document
cursortoxml( 'curStraightPoCtlg', 'lcXml', 2, 0, 0, '1' )
loElement = loXml.createElement( "poctlg" )
loCData = loXml.createCDATASection( lcXml )
loElement.appendChild( loCData )
loDocument.appendChild( loElement )


This creates a document, adds an elemtent, and adds CDATA section. You can then get the XML by doing loDocument.xml for the string, or send it to a file useing the Save() method. For attributes, use CreateAttribute() -- Mike Helland
Category XML
( Topic last updated: 2003.03.20 01:47:57 PM )