![]() |
|||
| Version
www.capesoft.com |
|||
Introduction
Features
[Suggested Reading]
What
xFilesXML Doesn't Do [Suggested Reading]
Limitations
Future
Ideas
What
is XML?
xFileXML Quick Start Guide
Loading
/ Importing & Parsing XML Files [Suggested Reading]
Creating an XML File or String
[Suggested Reading]
xFiles
Template [Suggested Reading]
Some
Practical Applications of the xFilesXML Class
[Suggested
Reading]
Loading XML Files
Creating RSS Feed Files
Storing Global Settings in an
XML file
Creating SOAP requests
Using a View to create a filtered, sorted,
XML file
Storing multiple things in the same XML file
Examples
Classes
xFileXML Class - XML loading and saving the easy way.
Jump
Start (great for new users and beginners)
[Suggested Reading]
xFileXML
Methods
xFileXML
Properties
xFileLinkDLL Class -
Runtime DLL Loading
xFileLinkDLL
Jump Start
[Suggested Reading]
xFileLinkDLL_Methods
xFileLinkDLL
Properties
FAQ
Support
Installation
Distribution
License
& Copyright
Version
History
![]()
CapeSoft xFiles is a collection of classes for hand-coders.
It provides the following functionality:
- Reading and writing XML files directly to and from Groups, Queues and Files (TPS, or any other backend). Support for writing xml from Views is also included.
- Fast reading and writing of XML files to and from Clarion data structure with no significant overhead for the XML - files are read from disk and written to disk at the speed at which a binary file can be read or written.
- Support for creating RSS feeds
- Support for creating simple SOAP server or SOAP client packets. (Not all SOAP possibilities are supported yet.)
- Automatic encoding of binary data, BLOB and MEMOs in XML. Automatic addition of CDATA tags when needed.
- XML support for nested queues and groups within queues, groups and files (Clarion 6 and above)
- XML support for fields with multiple dimension (Clarion 6 and above)
- Create XML in memory from queues, groups, views and files, or populate a queue, group or file from a string in memory that contains the XML.
- Use xFilesXML to load and save all program settings in one go using the Load and Save methods.
- xFileSettings class replaces storing settings in INI files with XML files, using Get and Put and the same syntax as is used for INI files.
- Reading and Writing binary (and text) files to and from disk. Includes dynamic memory allocation for loading any size file into memory (as a string).
- Supports automatic ZIP and UNZIP compression when reading and writing files (including XML files).
- Very high precision timers using the xFileFastTimer class. Uses 64bit precision for accurate, high resolutions timers.
- xFilesExplode supports decompressing files compressed with the proprietary Implode algorithm.
We wrote xFiles a number of years ago, and it provided fast XML functionality, which we used in a number of our products (CapeSoft Email Server and CapeSoft Mailer among others). It worked so well, that we decided others would benefit from using it too.
Note: xFiles is for hand coders. This means you will need to call the xFiles methods within your code, for example self.Load() and self.Save(). This accessory is not purely template driven and requires hand-coding to operate.
One of the best things about xFiles is that is it really, really fast (yeah, really, you will be surprised just how fast it is!). This means that it outperforms other XML toolkits (for example the Microsoft SAX toolkit).

![]()
Limitations
- File size must be less than 2.1 GB (2147483638 bytes).
- There is a maximum field name length for xFilesXML of 80 characters. This can be changed to any value desired.
- The maximum number of fields per File, View, Group or Queue is determined by the XF:MaxFields equate (This is 252 by default). This can be set to any value as required.
- xFiles support a small subset of compression (zip, unzip and explode). Compression support is very much Beta (feature incomplete), we would not advise using xFiles as a compression utility at this point - it compresses an XML file (or other file) into a ZIP file, and decompresses a file inside a ZIP, but it is not currently a generic ZIP or compression solution.
XML is an acronym for EXtensible Markup Language. It is an open standard for describing data in a standard, easy to use, format. XML uses a similar tag structure as HTML, however XML tags define what elements contain, and not the format for displaying them. While HTML uses predefined tags, XML allows tags to be defined by the developer. This makes XML extremely flexible, while still being easy to use. XML is an excellent format for transferring and storing information.
XML is more Rigid than HTML, it is not tolerant of errors, XML documents need to be "well formed", which means they must comply with fairly rigid rules.
XML and HTML Tags
Following are examples of XML and HTML tags. Note that the XML statements define data content, whereas the HTML lines deal with fonts and display (boldface). XML defines "what it is," and HTML defines "how it looks."XML
<firstName>Maria</firstName>
<lastName>Roberts</lastName>
<dateBirth>10-29-52</dateBirth>HTML
<font size="3">Maria Roberts</font>
<b>October 29, 1952</b>CapeSoft xFiles reads and writes basic XML, it does not currently support all possible XML, however it will read any XML files that it creates. The intent of xFiles is to be small, fast (very fast), and simple. It is not a generic XML parser and is not intended to read all possible XML documents, although we will expand the support for more complex XML in future versions.
Advantages of XML
- Robust, logically-verifiable format is based on international standards.
- The hierarchical structure is suitable for most (but not all) types of documents.
- XML Files are plain text files, unencumbered by licenses or restrictions
- Easily readable (by both human and machine).
- Also easily editable.
- Portable and compatible across multiple platforms (Windows, *nix, Mac etc.).
- It is platform-independent, thus relatively immune to changes in technology.
- It and its predecessor, SGML, have been in use for well over a decade, so there is extensive experience and software available.
For more information visit http://www.w3.org/XML/. XML definition and information based on content from http://www.answers.com/topic/xml.
![]()
![]() |
Keen to get started? Or just don't like wading through all the documentation? This section is just for you - the basics on how to get xFiles working as quickly and simply as possible. |
Things you need to know to load XML
XML Files come in all shapes and sizes, but reading them into a Clarion structure can usually be done with a single line of code. In additional the File can be either stored on disk, or already be in RAM as a string. Importing from either of these is trivial.
Creating the xml object in your procedure.
You can use the xFiles extension template to add an XFiles object to your procedure. Or you can hand-code the object declaration in the data section of your procedure. It'll look something like this;
xml xFileXML
Matching the field names to the XML.
The secret to the simplicity of the Load is that the NAME (or External Name attribute) of the fields you are loading matches the xml tags in the xml file. For example, if you have xml that looks like this:
<xml>
<server>www.capesoft.com</server>
<port>80</port>
</xml>
then your group should have the same field names:
Settings Group
Server String(80)
Port Long
End
xFiles simply matches up the names and the tags, and copies the data across for you.
In some cases the xml tags have names that are not legal Clarion field names. Or you may just want to change the tag name to match your field name. In this case set the External Name to match the tag name. For example:
<xml>
<web-server>www.capesoft.com</web-server>
<web-port>80</web-port>
</xml>
then in your group set the external names:
Whatever Group
Server String(80),Name('web-server')
Port Long,Name('web-port')
End
XML containing multiple records
In multi-record XML xFiles needs to know the FileBoundary and the RecordBoundary. These properties tell xFiles what part of the xml file to parse, and most importantly when a record is complete. For example in the following xml
<?xml version="1.0" encoding="US-ASCII"?>
<table>
<item>
<name>Bruce</name>
<age>29</age>
</item>
<item>
<name>Bob</name>
<age>40</age>
</item>
</table>
The file boundary is <table> (since all the records fall between <table> and </table>) and the record boundary is <item> (since the data we are interested in, the name and age, falls between <item> and </item>)
We can store this file in a Queue, which would look something like this;
NamesQueue Queue
name
String(20)
age Long
End
TIP: The first step is looking at the XML file in question and deciding on the most appropriate structure to load it into. A Group is best if the xml contains a "single record" and is typically used for program settings and things like that. If the structure contains a repeating structure (in other words, multiple records) then a Queue or File is more appropriate. Of course an In-Memory file can be used as a File rather than using a Queue.
TIP: Although a valid XML file always has a single FileBoundary, that wraps the XML from top to bottom, not all systems generate XML that conforms to this standard. So xFiles allows the FileBoundary to be blank. If it is blank, then xFiles parses the file as if there is no file boundary.
In the case of a Group, it is possible to set the RecordBoundary blank, and still have a valid XML file. For example;
<?xml version="1.0" encoding="US-ASCII"?>
<data>
<server>www.capesoft.com</server>
<port>80</port>
</data>
XML with Attributes
In this case the FileBoundary should be set to blank and the RecordBoundary should be set to data.
An alternative approach to XML, that the file you have may use, is the use of attributes. This is just another way of storing information. xFiles treats attributes on the record boundary exactly as if they were separate fields. For example;
<record firstname="bruce" lastname="brown">
<dob>1/1/2000</dob>
</record>
is processed as if it was
<record>
<firstname>bruce</firstname>
<lastname>brown</lastname>
<dob>1/1/2000</dob>
</record>
Loading an XML File from the disk into a Clarion Structure
Once you have determined the data structure you will be using, if it is a Queue or a File, you also need to determine the File Boundary and Record Boundary. Once you know that then importing the XML file is a single line of code.
xml.Load(Structure,XmlFileName,[FileBoundary],[RecordBoundary])
The last 2 parameters are optional in the case of a Group, but it's always
better to include them if you know what they are.
For example;
xml.Load(NamesQueue,'c:\temp\names.xml','table','item')
or
xml.Load(Settings,'.\settings.xml')
Loading an XML File from a string into a Clarion Structure
This is just as easy as loading it from a file. The syntax of the load method changes slightly to accommodate the name, and length, of the string instead of the file name. ie
xml.Load(Structure,String,Length,[FileBoundary],[RecordBoundary])
For example;
xml.Load(Settings,SomeString,len(clip(SomeString)))
or
xml.Load(NamesQueue,net.packet.bindata,net.packet.bindatalen,'table',item')
Tip:
Because the String parameter
is passed as a pointer, you can't put a constant in here, you must use a
variable. In other words the following will fail to compile;
xml.Load(Settings,'<server>www.capesoft.com</server>',100)
Loading XML from the Web into a Clarion Structure
When two programs want to communicate across the web they often pass their information formatted as XML. Web Services are nothing more than servers that answer "Questions" using XML. This XML is usually wrapped in a SOAP envelope, but not always. A SOAP envelope is nothing more than some extra XML stuff included in the packet.
In short, you do not need to be at all worried about Web Services, or SOAP. It's all just XML, and xFiles can handle it just like any other XML. However it arrives, it will be available to you as a string, and you can parse this string into a Clarion structure just as described in the section above.
Tip: Interacting with a Web Service typically consists of 2 parts. A Request, and a Response. This section deals with handling the Response. For more information on forming the Request, see the section [....]
If, for example, you have used a NetTalk WebClient object to fetch the XML from the server, then you would add a single line of code into the .PageReceived method to parse the incoming reply into a Group, Queue or File. For example, the Convert example does it with this line;
xml.load(resultGroup,self.page,len(clip(self.page)),'','ChangeLengthUnitResponse')
If that page was an RSS feed, then the following line would copy the feed into a Queue.
xml.load(RssQueue,self.page,len(clip(self.page)),'channel','item')
The Queue declaration would look something like this;
RssQueue QUEUE,PRE(rss)
Title STRING(255)
Link STRING(255)
Description STRING(1024)
END
![]()
![]() |
Keen to get started? Or just don't like wading through all the documentation? This section is just for you - the basics on how to get xFiles working as quickly and simply as possible. |
In the same way that you can load an XML file into a Clarion structure, you can also create XML files very quickly and easily.
Saving a Clarion Structure to an XML file on the Disk
Saving a Clarion structure to an XML string in Memory
Properties which can be set before a call to Save
Properties which can be set in
SaveTweakFieldSettings
Methods which can be used during a Save
Saving a Clarion Structure to an XML file on the Disk
xml.Save(Structure,XmlFileName,[FileBoundary],[RecordBoundary])
The last 2 parameters are optional but it's always
better to include them if you know what they are. Note that if you include one
you will need to include both. In the case of a Group, the FileBoundary can be a
blank string.
For example;
xml.Save(NamesQueue,'c:\temp\names.xml','table','item')
or
xml.Save(Settings,'.\settings.xml')
You can use a Group, Queue, View or File as the structure holding the data being saved.
the method returns 0 if successful, non-zero otherwise. If not successful the errorcode will be in the .Error property, and a description of the error will be in the .ErrorStr property.
Saving a Clarion structure to an XML string in Memory
xml.Save(Structure,XmlFileName,[FileBoundary],[RecordBoundary])
This is the same as saving the xml to a File, except that the XmlFileName parameter is not used. After the call to save, the xml data will be in the property xmlData. The length of this string is in XmlDataLen. For example;
xml.save('NamesQueue')
Blob[1 : xml.XmlDataLen] = xml.XmlData
Properties which can be set before a call to Save
There are a number of properties which you can set just before doing a save. These properties affect the way the Xml looks.
| Property | Effect |
| DontReplaceColons | By default colons in the field name are replaced with a period. If you wish to suppress this behavior then set this property to 1. |
| OmitXMLHeader | The XML header (usually <?xml version="1.0">) is not added to the top of the file. |
| _pFileBoundary | Typically passed as a parameter of the call to .Save.
This sets the boundary for the outside of the file. <?xml version="1.0"> <file> <record> </record> </file> |
| _pFileBoundaryAttribute | Can be set to allow an attriute string to be included
as part of the file boundary. <?xml version="1.0"> <file albert="fat"> <record> </record> </file> |
| _pRecordBoundary | Typically passed as a parameter of the call to .Save.
This sets the boundary for each record inside the file. <?xml version="1.0"> <file> <item> </item> </file> |
| _pRecordBoundaryAttribute | An attribute string for the record boundary <?xml version="1.0"> <file> <item albert="fat"> </item> </file> |
| RemovePrefix | Default is 1. If set, the prefix is not used when matching fields to tags. |
| RootBoundary | An additional XML boundary around the whole file. <?xml version="1.0"> <root> <file> <record> </record> </file> </root> |
| RootBoundaryAttribute | A string of attributes for the Root Boundary. <?xml version="1.0"> <root albert="fat"> <file> <record> </record> </file> </root> |
| RSSVersion | If you are creating an RSS file, set this property to
the RSS version you are using. For example 2.0 <?xml version="1.0" encoding="ISO-8859-1"?> <rss version="2.0"> If the RssVersion propert is set, the _pFileBoundary is automatically set to <channel> |
| SaveEncoding | The encoding scheme to use for the XML file. Examples
are 'utf-8', 'ISO-8859-1' and 'windows-1252'. <?xml version="1.0" encoding="utf-8"> |
| SaveBlobsAsCData | Default is 1. Blob fields will be encoded as [CDATA] in the XML file. This is necessary for blobs containing binary characters. (ie Non ASCII characters) |
| SaveMemosAsCData | Default is 1. Memo fields will be encoded as [CDATA] in the XML file. This is necessary for memos containing binary characters. (ie Non ASCII characters) |
| SaveStringsAsCData | Default is 0. If set all String fields will be encoded as [CDATA] in the XML file. This is necessary for strings containing binary characters. (ie Non ASCII characters). You can set this property for individual fields. (See Properties which can be set in SaveTweakFieldSettings) |
| StandAlone | Allows you to set the StandAlone property in the xml
header. Can be set to 'yes' or 'no'. <?xml version="1.0" standalone="yes"> |
| SoapBodyBoundary | The name of the SOAP Body boundary. The default is
soap:Body. Only used if .SOAPEnvelope property is set to 1. <?xml version="1.0"> <soap:Envelope> <soap:Body> <file> <record> </record> </file> </soap:Body> </soap:Envelope> |
| SOAPEnvelope | Set this to 1 to include the SOAP envelope boundary (and Soap Body boundary) around the file. |
| SOAPEnvelopeBoundary | The name of the SOAP Envelope boundary. The default is
soap:Envelope. Only used if .SOAPEnvelope property is set to 1. <?xml version="1.0"> <soap:Envelope> <soap:Body> <file> <record> </record> </file> </soap:Body> </soap:Envelope> |
| SOAPEnvelopeBoundaryAttribute | An attribute for the soap:Envelope boundary. The
default is xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" <?xml version="1.0"> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <file> <record> </record> </file> </soap:Body> </soap:Envelope> |
| ZipUseZip | Only valid for saving to an XML file on disk. If set, the XML file on disk will be compressed, using the ZIP compression scheme. |
Properties which can be set in SaveTweakFieldSettings
These properties are an array, where the array index is the field number of each field in the Group, Queue, File or View record. Setting these properties allows you to modify behaviour for individual fields in the record.
| Property | Effect |
| ColumnDisabled[x] | If this is set to 1 then the field is not exported to the XML file. If the field is inside a group, then you should adjust the _sGroupLen[x] property as well. |
| _Dimension[x] | If this field is an array, then this contains the size of the array. Note that multi-dimensional arrays are always stored as single dimensioned arrays internally. Bob,dim(5,5) is the same as Bob,dim(25). |
| _sFieldName[x] | The name of the field (In other words the <tag> name). If you change this be sure to change the _sFieldNameLen[x] property as well. |
| _sFieldNameLen[x] | The length of the _sFieldName[x] property. |
| SaveAsBase64[x] | Force this field to be saved as Base64. (Not currently used). |
| SaveAsCData[x] | Force this field to be encoded as [CDATA]. Useful for string fields that contain non-Ascii characters. |
| _sGroupLen[x] | If this field is a group, this contains the number of fields inside the group. If you disable fields inside a group, you should adjust this property as well. |
| _Over[x] | If this field is Over another field, then the parent field number is here. |
Methods which can be used during a Save
These methods allow you to embed code that affects the Save as it is happening.
| Method | Effect |
| SaveCurrentFieldToXML | This method is called for each field as the XML string is created. The first parameter is the field number. This provides you an opportunity to alter the value in the field before it is saved to XML. |
| SaveTweakFieldSettings | Allows you to set field related properties before the save commences. |
| SaveTweakSettings | Allows you to override properties explicitly set in the Init method. |
| ValidateRecord | This method is
called for each record while looping through the Queue, File or View.
You can add your own filter code to this method. Return one of XF:OutOfRange : Terminates the loop immediately XF:Filtered : Cycles to the next record without saving this one to the XML file. XF:Ok : Record is saved to the XML. |
![]()
Check out the Some Practical Applications section for other practical applications for xFiles.
![]()
![]()
Generic xFiles Template (to use an
xFiles object)
Export to/Import from XML Control Template
In order to use xFiles, you need to add the Global Extension Template initially:
Click on the
Global button, and Choose "Extensions", then press the "insert" button.
Choose the "ActivatexFiles - Activate Capesoft's xFiles" from the 'Class xFiles - CapeSoft xFiles - Version x.xx" section.
Remove File Prefix from field Labels - removes the file prefix from fields labels that are entered into the XML file. Note: these settings must match on import and export (if using a different instance of this control template to do the other import/export)
Replace colon in field name with a dot - if checked, all colons in field names are replaced with a dot in the XML tags (a colon is an invalid character in an XML tag)
Encoding method - allows you to select whether to use iso-8859-1, utf-8 or windows-1252. The default method is iso-8859-1, but you can force it to one of the others if you prefer.
Set Logging to - allows you to force debug logging on or off - otherwise you can use the compile time settings that are in the classes (normally off).
Customize Header and Footer - allows you to enter a customizable Header and or Footer (for things like RSS Feeds, etc).
Field Type Overrides - if you don't want to save MEMOs and/or BLOBs into your XML file, then you can disable this with these checkboxes.
CDATA Saving - you can encase your data in CDATA tags - you can select which field type you would like to do this for using these checkboxes
xFiles provides a template to make it simple to add an object to a procedure. To use the template:

The class details tab allows properties to be added to the class and methods to be added, overloaded or customised and provides access to the method and data embeds for the object.
You can populate this control template onto a window, and export a file/queue/group to a file from a button on the window.
![]()
You can setup the following options in the control template:

Local Data - the data source (typically this would be the name of the file to export - or the queue or group)
XML File - the file to export the data to. You can use quotes or a variable name.
Display Status - shows a message after exporting or importing the file.
ThisWindow.Reset(1) - resets the window after loading the file, forcing your browses and fields to be refreshed.

Remove File Prefix from field Labels - removes the file prefix from fields labels that are entered into the XML file. Note: these settings must match on import and export (if using a different instance of this control template to do the other import/export)
Encoding method - allows you to select whether to use iso-8859-1, utf-8 or windows-1252. The default method is iso-8859-1, but you can force it to one of the others if you prefer.
Set Logging to - allows you to force debug logging on or off - otherwise you can use the compile time settings that are in the classes (normally off).
Customize Header and Footer - allows you to enter a customizable Header and or Footer (for things like RSS Feeds, etc).
Field Type Overrides - if you don't want to save MEMOs and/or BLOBs into your XML file, then you can disable this with these checkboxes.
CDATA Saving - you can encase your data in CDATA tags - you can select which field type you would like to do this for using these checkboxes
Loading XML Files
Creating RSS Feed Files
Storing Global Settings in an
XML file
Creating SOAP requests
Item
QUEUE,PRE()Your queue must be labeled 'Item' and have the 'Title', 'Description' and 'Link' fields present. You can include additional fields for extra information as well (which will be ignored by the RSS aggregator).
ThisXMLFile.CustomSectionAfterFileBoundary = '<title>My RSS Feed</title><13,10>' |
& ' <description>My Description</description><13,10>' |
& ' <link>www.mywebsite.com</link><13,10>' |
& ' <language>en-US</language><13,10>' |
& ' <webMaster>webmaster@mydomain.com</webMaster><13,10>'
! This will load the existing RSS feed into our RSS feed queue
ThisXMLFile.RSSVersion = '2.0' ThisXMLFile.load(RSSFeedQueue,'RSSFeedfile.xml')
Item.Title = 'My New Item'
Item.Description = 'My new RSS feed description'
Item.Link = 'www.mywebsite.com\MyNewItem.htm'
Add(Item,1)
ThisXMLFile.save(RSSFeedQueue,'RSSFeedfile.xml')
This will create the file locally, and you'll need to upload it (which you will require an FTP process - ideally like NetTalk's SendFTP).
Many people are used to storing global settings in INI files, or perhaps a registry. There' s a much easier way using xFiles to store global settings. Because xFiles stores (and retrieves) a generic group structure, you can add variables without worrying about updating your store variable procedure. The only thing you need to be aware of is that variables stored (and retrieved) must be within a group structure. For example:
GlobalSettings
group, pre(GLOSET)
! Everything in this group will be stored in the XML
settings file
WebSite string(252)
EmailAddress
string(252)
end
FTPPostWindowThread long ! Not stored in
the XML settings file - we don't want this stored.
In our code, we simply call the save (and load) command for storing (and retrieving) the global settings we require preserved:
ThisXMLFile.save(GlobalSettings,'GlobalSettingsFile.xml')
and
ThisXMLFile.load(GlobalSettings,'GlobalSettingsFile.xml')
SOAP Servers are programs out on the network that you can interact with. Each program is different, but a protocol, SOAP, exists which makes it possible for different programs to communicate with each other.
SOAP packets are usually passed between programs using TCP/IP connections, and wrapped with a HTTP header. A tool like NetTalk makes this really easy to do. However inside the packet the request is formatted using XML, and thus XFiles can be very useful in this regard.
A complete description of SOAP is beyond the scope of this document, however you do not usually need to be a SOAP expert in order to make simple SOAP servers and clients.
You will find some working examples in \Clarion\3rdParty\Examples\SOAPClient. These examples use NetTalk to run, but you can convert them to use other networking tools if you wish.
A SOAP envelope is automatically wrapped around your regular XML if you set the SOAPEnvelope property to 1.
A typical SOAP request looks like this;
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ChangeLengthUnit xmlns="http://www.webserviceX.NET/">
<LengthValue>5</LengthValue>
<FromLengthUnit>Centimeters</FromLengthUnit>
<ToLengthUnit>Inches</ToLengthUnit>
</ChangeLengthUnit>
</soap:Body>
</soap:Envelope>
However different soap servers require different specific tags. To support this xFiles allows you to set the specific text for each part of the packet. Here is the request again, but this time I've replaced the optional parts with the name of the property you can set.
<?xml version="1.0" encoding="SaveEncoding"?>
<SOAPEnvelopeBoundary
SOAPEnvelopeBoundaryAttribute>
<SOAPBodyBoundary>
<_pFileBoundary
p_FileBoundaryAttribute>
<_pRecordBoundary
_pRecordBoundaryAttribute>
<LengthValue>5</LengthValue>
<FromLengthUnit>Centimeters</FromLengthUnit>
<ToLengthUnit>Inches</ToLengthUnit>
</_pRecordBoundary>
</_PFileBoundary>
</SOAPBodyBoundary>
</SOAPEnvelopeBoundary>
The above properties can all be set in the SaveTweakSettings method. Note that the _pFileBoundary tag is optional, and should be set to nothing if it is not required.
Other properties you need to set are .SOAPEnvelope (set to 1 to wrap the XML in a Soap Envelope) and .TagCase (usually you need to set this to XF:CaseAsIs - more on that in a moment.)
For example, the code to create the packet above looks like this
xml.SOAPEnvelope = 1
xml.SaveEncoding = 'utf-8'
Xml._pFileBoundary = ''
Xml._pRecordBoundary = 'ChangeLengthUnit'
Xml._pRecordBoundaryAttribute = 'xmlns="http://www.webserviceX.NET/"'
Xml.TagCase = XF:CaseAsIs
xml.SOAPEnvelopeBoundaryAttribute = &|
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
& |
' xmlns:xsd="http://www.w3.org/2001/XMLSchema"'
&|
' xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"'
xml.SOAPEnvelopeBoundary = 'soap:Envelope'
xml.SOAPBodyBoundary = 'soap:Body'
For the actual XML in the middle, a simple group is all that is required.
RequestGroup GROUP,PRE(Request)
LengthValue DECIMAL(9,3),NAME('LengthValue')
FromLengthUnit STRING(32),NAME('fromLengthUnit')
ToLengthUnit STRING(32),NAME('toLengthUnit')
END
(Take notice of the Name attribute, more on that in a minute.)
After setting all the values in the group to their desired state, you can then create the PostString (ready for the NetTalk side of things) using 2 simple lines of code.
xml.Save(RequestGroup)
PostString = xml.xmldata
The call to Save converts the group into XML, and stores the result in the .XmlData property. Because the .SOAPEnvelope property (and all the other properties) have been set appropriately in SaveTweakSettings, the text that is in .XmlData is the complete SOAP request.
It is worth mentioning a slight complication alluded to earlier which needs
to be taken into account. Most SOAP servers are picky, and require the tag names
to be case sensitive. In other words
<LengthValue>5</LengthValue> is not the same as
<lengthvalue>5</lengthvalue> which is not the same
as
<lengthValue>5</lengthValue>
The most common mistake when speaking to a SOAP server is getting these tag names not-quite-right, and hence the server returns an error. xFiles supports a variety of possible tag cases (when creating the XML) and these are set using the .TagCase property as we saw above. Possible values for .TagCase are XF:CaseLower, XF:CaseUpper, and XF:CaseAsIs.
If your SOAP server requires upper, or lower case tags, then you don't need to worry about the External Name for each field, just set the .TagCase property to the appropriate value and continue. If however the server requires a mixed case (as this example does) then you need to set the Name for each item in your group. Be very careful with the case - in this example the LengthValue tag started with a capital letter, but the fromLengthUnit tag did not.
Using a View to create a filtered, sorted, XML file
Exporting a whole data table, including all records and all fields to an xml file is easy. Simply use the .Save method. For example
xFileXML.Save(Customers, 'customers.xml')
If however you only want to export a subset of the fields, or records, or if you want to specify the sort order for the export, then the above command is too limited. In this case what you need to do is export the xml using a VIEW as the data source, rather than a file.
The Dict example, which you'll find in the \clarion\3rdparty\examples\xfiles\dict folder has an example of creating a view, and then using it to create the xml file.
For example
xml xFileXml
ThisView View(Wages)
Project(wag:Employee)
End
code
xml.Save(ThisView,'employees.xml')
The important thing to remember about views is that you get to decide which fields are included, and which are excluded. In addition you decide what the FILTER and ORDER properties for the view are.
Last, but not least, it's useful to remember that all Browses and Reports in your application are based on Views. Thus it is possible to export the contents of a Browse, or Report, to XML but using this xFiles function, and making use of the views constructed for you by these templates.
Storing multiple things in the same XML file.
Up to now all the examples have shown a single entity (Group, Queue, File or View) being stored in an XML file. However it is possible to store multiple entities in the same file.
In order to place multiple entities in the same xml file the following basic steps occur;
1. Get the class ready, by setting the Root-Node (the wrapper around the whole thing) and telling the class not to automatically close the root node.
xml.RootBoundary = 'whatever'
xml.DontCloseTags = 1
2. Save the first entity as normal
xml._pFileBoundary = 'Document'
xml.Save(ReportFormat ,Loc:XmlName)
3. Set the append flag so the following items are appended
xml.append = 1
4. Add as many entities to the file as you like, using the normal techniques. Although the boundaries do not have to be unique you may chose to make them unique so they can be loaded separately later on.
xml._pFileBoundary = 'DefnFieldsLocal'
xml.Save(rrDefnFieldsLocalView,Loc:XmlName)
xml._pFileBoundary = 'DefnFieldsGlobal'
xml.Save(rrDefnFieldsGlobalView,Loc:XmlName)
5. Finally before sending the final entity, tell the object to close the root tag.
xml.DontCloseTags = 0
xml._pFileBoundary = 'DefnBandControls'
xml.Save(rrDefnBandControlsView,Loc:XmlName)
NOTE: This approach cannot be used if a zipped xml file is being made using the built-in zipping classes.
![]()
Examples
Notes on getting started.
The examples are an excellent place to get started. The JumpStart example
is a quick and easy way to see how to use xFiles with the minimum of code or
effort. The xFiles Demo example is also an good place to see a few of the basic
uses of xFiles, it uses the xFileXML and xFileBinary
classes and demonstrates a few of the basic of using xFiles classes.
| xFiles Examples | |||
| Jumpstart | Clarion\3rdparty\Examples\xFiles\JumpStart The result of following the JumpStart section. The most basic example of how to use xFiles. The app file is xfJump.app. See JumpStart for more details. |
||
| Demo | Clarion\3rdparty\Examples\xFiles\Demo A basic example of using xFiles, this example exports a browse (either as a Queue, or as a View) to an XML file. It also demonstrates the usage of the xFileBinary class to load the XML file into a string so that it can be displayed. |
||
| Demo FE | Clarion\3rdparty\Examples\xFiles\Demo FE This is a modified version of the Basic example. It uses File Explorer to display the XML instead of loading the string into a text control. This allows the XML to be displayed with color syntax highlighting and interactivity. The example is identical except for the ViewXML window which doesn't use the xFileBinary class, it just displays the XML file using File Explorer. See www.capesoft.com/accessories/filesp.htm for more information on CapeSoft File Explorer. This example is for Clarion 5.5 and above (File Explorer does not support Clarion 5). |
||
| Demo Full |
Clarion\3rdparty\Examples\xFiles\Demo Full A fuller example application, which
also demonstrates creating the XML from a queue in memory (using a string)
as well as writing to a file and loading the XML file into the browse
queue. This example will grow significantly in future releases to demonstrate
the full functionality of xFiles. |
||
| Dict | Clarion\3rdparty\Examples\xFiles\Dict An example of source procedures in an app that export a file to xml, and a view to xml. |
||
| Simple Project | Clarion\3rdparty\Examples\xFiles\Simple Project A very simple project and CLW file. Includes the xFiles.inc
files and uses a xFileBinary object to write data to disk. |
||
| Convert | Clarion\3rdparty\Examples\xFiles\SOAPClient\Convert A simple SOAP example that connects to a SOAP server out on the web. |
||
![]()
Classes
This lists the Classes provided by xFiles at
this time, along with a description of the functionality provided by each class.
| xFiles Classes | |||
| xFileBinary | Binary file
handling - high speed reading and writing of all file types (binary and
text) with minimal coding (simply call a single method to load the file
into memory using a string or save a file from memory to disk.) |
||
| xFileExplode | Handling decompression of files
compressed using the PKWare implode/explode algorithm. Does not support
compression. |
||
| xFileFastTimer | High speed,
accurate timers. |
||
| xFileLinkDLL | Easy support for run time linking
of DLLs and locating procedures in the DLLs when loaded.
Click Here To see the
QuickStart guide. |
||
| xFileSettings | An easy to
use replacement for GetINI and PutINI - writes to XML files instead of
INI files. |
||
| xFileXML | Write any queue, group, view or file to
an XML file
and read XML files directly into a queue, file or group.
Click Here to see the QuickStart guide. |
||
| xFileZip | Handles compression
and decompression using a ZIP algorithm. |
||
| xFileBase | Internal
base class, does not contain accessible functionality |
||
| xFileBaseCompress | Internal
base class for compression |
||
The methods for each class is listed below, along with a fuller explanation of what the classes do. See the Examples for more. Please note this section of the documentation is under construction and we are expanding it to include all class methods and a full description, usage information, examples etc.
| xFileXML Methods | |||
| The XFileXML class provides the ability to easily load XML files from disk into a group, file or queue, and save a group, file, view or queue to disk as an XML file. Writing a data structure to disk can be done by calling a single Save method. Similarly, reading an XML file into a group, file or queue is as simple as calling the Load method. |
|||
| AddRecord | Add a record to the object loaded by xFileXML (queues and files only). | ||
| Copy | Copy data to or from the data structure being used by xFileXML. Allows the contents of a queue to be copied into a File being used, or data from a different queue or group to be copied into the queue or group used by the xFileXML object. | ||
| Init | Initialise an xFileXML object to use a particular queue and data structure. | ||
| Load | Load from file to the data structure. | ||
| Save | Save to the XML file (or create the XML in memory). | ||
| Advanced Class Methods | |||
| Generic File Loading and Saving | |||
| SaveBinData | Saves the binData string property to the file name specified. | ||
| LoadBinData | Loads a file into the binData string property. | ||
| XML file modification and settings | |||
| CreateFooter | Creates a string that is appended after the file data. | ||
| CreateHeader | Creates the XML header that is added to the file. | ||
| LoadTweakSettings | Called when the Save is about to be done to allow the object setting to be modified before the save code is executed. | ||
| SaveTweakSettings | Called when the Load is about to be done to allow the object setting to be modified before the load code is executed. | ||
| Record handling and management | |||
| GetValue | Gets a value of a field when passed the field name (Files only). | ||
| SetValue | Sets the value of a field when passed the name and value (Files only). | ||
| InsertFileRecord | Inserts a record in the file (File only). | ||
| UpdateFileRecord | Updates a record in the file (File only). | ||
| RecordCount | Returns the number of records in the file or queue. | ||
| FreeFileData | Deletes all records in the file. | ||
| FreeGroupData | Clears the group. | ||
| FreeQueueData | Deletes all queue records. | ||
| ValidateRecord | Used when reading into a Queue, or File, or writing from a Queue, File, or View. This method allows you to suppress records by returning the value | ||
| AddOldField | If one of the fields in your Group, Flie, Queue or View has changed, and exported XML files exist that are still using the old field names, you can use this to tell XFiles to import the the value into the renamed field. | ||
| LoadAllOldFields | This is called when Load is called. Embed your calls to AddOldField() here, after the parent call. | ||
| xFileXML Properties | |||
|
|
|||
| dontReplaceColons | Replaces colons with full stops when writing prefixes to the file (on by default) | ||
| loadFields | Specify the number of fields to load | ||
| saveFields | Specify the number of fields to save | ||
| addFields | Set the number of fields to add when the AddRecord() method is called | ||
| dontLoadLastFields | Exclude certain fields when loading | ||
| dontCopyLastFields | Exclude certain fields fields when the Copy() method is called | ||
| dontAddLastFields | Exclude certain fields when the AddRecord() method is called | ||
| columnDisabled | An array of columns that allows specific columns to be ignored when loading and saving | ||
| _pFileBoundary | A custom boundary for the XML data (the tag that begins and ends the data being read or written). If this property is set to nothing then it will be ignored. | ||
| _pFileBoundaryAttribute | Added to the file boundary tag when writing an XML file. | ||
| _pRecordBoundary | A custom boundary tag for delimiting records in the XML file | ||
| _pRecordBoundaryAttribute | Added to the record boundary tag when writing an XML file. | ||
| binData | The internal string that stores data being read or written to and from XML files | ||
| binDataLen | The length of the internal data storage (binData) string | ||
| xmlData | A string that stores the XML created when using the loadFromString and saveToString options | ||
| xmlDataLen | The length of the xmlData property in bytes. | ||
| saveToString | Modifies the Save() method's behaviour so that it creates the XML and save it to the xmlData property rather than writing it to disk (save to memory). | ||
| SOAPEnvelope | Set this to 1 to generate a SOAP heading, and envelope, around the XML. | ||
| SOAPEnvelopeBoundary | Sets the <Soap:Envelope> tag | ||
| SOAPEnvelopeBoundaryAttribute | Optionally include attributes in the <Soap:Envelope> tag | ||
| SOAPBodyBoundary | Sets the <Soap:Body> tag | ||
| TagCase | Determines the case of the field Tags in the XML. Set to XF:CaseLower (default), XF:CaseUpper or XF:CaseAsIs. | ||
| loadFromString | Modifies the Load() method's behaviour so that it loads directly from memory using the xmlData property rather than loading from a file. | ||
| OmitXMLHeader | Creates the XML files without the header line | ||
![]()
| xFileLinkDLL Methods | |||
| The xFilesLinkDLL class provides runtime DLL loading. This allows you to load a DLL when your program is running and access functions provided by that DLL. The DLL itself is not linked into your application at compile to using a LIB file. This is useful when your application depends on an external DLL, or there is functionality that is only provided when a particular DLL is available, or for functions that are specific to certain version of Windows etc. |
|||
| Construct | Constructor that is called when the object is created. | ||
| Destruct | Destructor that is called when the object is destroyed. | ||
| LinkDLLFunction | Loads a function from a DLL. If the DLL is not already loaded it loads the library. | ||
| Init | Initialisation method, does not perform any functionality and is provided for overriding the default behaviour. | ||
| xFileLinkDLL Properties | |||
| dontDisplayMessages | Replaces colons with full stops when writing prefixes to the file (on by default) | ||
| _DLLModules | Specify the number of fields to load | ||
![]()
xFileXML.AddRecord
(<any p_F1>,<any p_F2>,<any p_F3>, ...)
Adds a record to the xFilesXML record queue. The method takes up to 20 ANY parameters,
which allows the addition of records to a queue where the type of a field is
not known.
Parameters:
| Parameter | Description |
| <any p_F1>,<any p_F2>,<any p_F3>, ... | Up to 20 parameters of the ANY type can be passed. Each parameter populates a field in the record that is to be added to the queue. |
See Also:
xFileXML.Load(), xFileXML.Save()
xFileXML.Copy (*Group p_Group, byte p_Direction=0)
xFileXML.Copy (*Queue
p_Queue, byte p_Direction=0)
Copies the records from the internal xFileXML group/queue property to the passed
group/queue, or from the passed group/queue to the xFiles group/queue. The direction
parameter specifies whether the data is copied from the parameter to the xFilesXML
property or from the property to the passed variable.
Parameters:
| Parameter | Description |
| *Group p_Group or *Queue p_Queue | The queue or group to copy to or from (depending on the value of the direction parameter). |
| byte p_Direction | If p_Direction is 0 then records are copied from xFilesXML to the passed group/queue. If p_Direction is 1 then the data is copied from the xFilesXML object to the passed group/queue. |
See Also:
xFileXML.Load(), xFileXML.Save()
xFileXML.Init
(*Queue p_Queue, string p_FileName)
xFileXML.Init (*Group
p_Group, string p_FileName)
xFileXML.Init (*File p_File, string p_FileName)
xFileXML.Init (*View p_View, string p_FileName)
Initialises the xFileXML object to the a particular data structure and file, you can call this method at any point to change the data structure that is read from and written to, and the XML file that is used. If you are setting any of the class properties such as LoadFields and SaveFields then Init must be call after setting the class properties in order to use them.
Note: As well as passing a Queue, you can also pass a Group, File or View to the Init method to have xFiles read and write using a group, file, view or queue. (Views are Write-Only, not Read).
Note: You don't need to call Init
unless you set advanced class properties like xFileXML.loadFields, xFileXML.saveFields
and xFileXML.copyFields. If you set these properties to change which fields
are saved then you need to use the first method above and call Init().
Otherwise you can call the Load and Save methods and pass them the queue/group/file/view
and file name without calling Init().
Parameters:
| Parameter | Description |
| *Queue p_Queue or *Group p_Group | The label of the queue or group that the data is read from and written to. |
| string p_FileName | The name of file to read from and write to. |
Examples
| Example |
! DATA
myQueue queue
from string(80)
to string(80)
end
xmlFileName string(260)
! CODE
xmlFileName = 'myXmlFile.xml'
thisFileXML.Init(myQueue, xmlFileName)
|
See Also:
xFileXML.Load(), xFileXML.Save()
xFileXML.Load
(*Queue p_Queue, string p_fileName, <string p_FileBoundary>,<string
p_RecordBoundary>)
xFileXML.Load (*Group
p_Group, string p_fileName, <string p_FileBoundary>,<string p_RecordBoundary>)
xFileXML.Load (*File p_File, string p_fileName, <string p_FileBoundary>,<string p_RecordBoundary>)
xFileXML.Load (*Queue p_Group, *String p_XMLString, Long p_XMLStringLength, <string p_FileBoundary>,<string p_RecordBoundary>)
xFileXML.Load (*Group p_Group, *String p_XMLString, Long p_XMLStringLength, <string p_FileBoundary>,<string p_RecordBoundary>)
xFileXML.Load (*File p_File, *String p_XMLString, Long p_XMLStringLength, <string p_FileBoundary>,<string p_RecordBoundary>)
xFileXML.Load
()
Loads an XML file into the data structure.
The first parameter is the Clarion data structure that will receive the parsed XML. Valid structures are a Queue, File or Group.
The second parameter is the name of the file on disk, or the name of the string which is holding the XML in memory. If the XML is in a string, then an additional parameter, the length of the string, is required at this point.
Following this are 2 optional parameters that allow you to specify the File Boundary, and Record Boundary tags.
The .Load method (no parameters) ultimately loads the XML
into the specified structure. It is included here for completeness but it should
not usually be called directly.
Parameters
| Parameter | Description |
| *Queue p_Queue or *Group p_Group or *File p_File |
The queue, file or group that the xml data will be loaded into. |
| string p_FileName | The name of file to read from. |
| *String p_XMLString | The string variable containing the whole, valid, XML data. |
| Long p_XMLStringLength | The length of the XML string. |
| <string p_FileBoundary> | The file boundary tag in the XML file. Optional. Default is file, view, queue or group. If the p_FileBoundary parameter is set then the p_RecordBoundary parameter must be set as well. |
| <string p_RecordBoundary> | The Record boundary tag in the XML file. Optional. Default is item (for File or Queue) or data (for Group). If the p_RecordBoundary parameter is set then the p_FileBoundary parameter must be set as well. |
Examples
| Example 1 - Calling Load by passing the data structure and file name. |
! DATA
myQueue queue
from string(80)
to string(80)
end
xmlFileName string(260)
CODE
xmlFileName = 'myXmlFile.xml'
thisFileXML.Load(myQueue, xmlFileName)
|
| Example 2 - Calling Load after calling Init |
! DATA
myGroup group
from string(80)
to string(80)
end
xmlFileName string(260)
CODE
xmlFileName = 'myXmlFile.xml'
thisFileXML.Init(myGroup, xmlFileName)
thisFileXML.Load()
|
See Also:
xFileXML.Save(), xFileXML.Init(), Loading XML Files
xFileXML.Save
(*Queue p_Queue, string p_fileName, <string p_FileBoundary>,<string
p_RecordBoundary>)
xFileXML.Save (*File p_File, string p_fileName, <string p_FileBoundary>,<string p_RecordBoundary>)
xFileXML.Save
(*View p_View, string p_fileName, <string p_FileBoundary>,<string
p_RecordBoundary>)
xFileXML.Save (*Group
p_Group, string p_fileName, <string p_FileBoundary>,<string p_RecordBoundary>)
xFileXML.Save
(*Queue p_Queue, <string p_FileBoundary>,<string p_RecordBoundary>)
xFileXML.Save (*File p_File <string p_FileBoundary>,<string p_RecordBoundary>)
xFileXML.Save
(*View p_View <string p_FileBoundary>,<string p_RecordBoundary>)
xFileXML.Save (*Group
p_Group <string p_FileBoundary>,<string p_RecordBoundary>)
xFileXML.Save ()
Saves a Clarion data structure into an XML file, or string.
The first parameter is the Clarion data structure that holds the data to be exported. Valid structures are a Queue, File, View or Group.
The second parameter is the name of the file on disk. If the XML is to be stored in a string, in memory, then this parameter is ignored.
Following this are 2 optional parameters that allow you to specify the File Boundary, and Record Boundary tags.
The .Save method (no parameters) ultimately saves the XML into the file or string. It is included here for completeness but it should not usually be called directly.
Parameters: