xFiles Documentation
Introduction
CapeSoft xFiles is a collection of classes for hand-coders. It was built
primarily to provide a simple, yet exceptionally high-performance method to
convert xml files or strings to Clarion data structures, and vice-versa.
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.
- Automatic encoding of binary data, BLOB and
MEMOs in XML. Automatic addition of CDATA tags when needed.
- XML support for nested 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.
Note:
xFiles is primarily for hand coders. This means you will need to call the xFiles methods within your code.
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).
Features of the xFilesXML Class
- Writes a Queue, Group, View or File to an XML file simply by calling the self.Save() method.
- Reads an XML file into a data structure (Queue, Group or File) by calling the self.Load() method.
- Reads and Writes XML files fast and reliably.
- No knowledge of XML is required.
- The xFileXML class also allows application settings (for example global application settings stored in a global group) to be stored
in XML files.
- Alternatively the xFileSetting class can be used to replace settings that you would previously have stored in INI files. This class uses
XML files for ultra fast, reliable storage of settings.
- Thread safe.
- Includes a number of extra utility classes for providing high precision timers, API runtime DLL linking, and basic zip compression.
- xFiles is Clarion Source Code. This means that your application is not dependent on external DLLs or Microsoft toolkits. The xFiles classes
are compiled into your application and they run on all flavors of the Windows Operating Systems.

What xFilesXML Doesn't Do
Originally built on a fairly limited subset of XML, xFiles has grown to allow the creation, and consumption of most
XML constructions. If you find a construction that it does not support please let us know as we endevour to support all legal
XML formats.
Limitations
- File size must be less than 2.1 GB (2147483638 bytes).
- There is a default maximum tag name length, determined by the
XF:MaxFieldNameSize equate (currently 100 characters).
This can be extended if necessary. Contact us for more details.
- The maximum number of fields per
File, View, Group or Queue is determined by the XF:MaxFields
equate (This is 1024 by default). This can be set
to any value as required.
- xFiles supports 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.
What is XML?
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>Maria Roberts</font>
<b>October 29, 1952</b>
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.
xFileXML Quick Start Guide - Loading, Importing and Parsing 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
Attributes
XML allows attributes to be assigned to a tag. For example;
<xml>
<server protocol="http">www.capesoft.com</server>
<port>80</port>
</xml>
This is equivalent to;
<xml>
<server>www.capesoft.com</server>
<protocol>http</protocol>
<port>80</port>
</xml>
xFiles parses incoming attributes exactly as if they were tags. So the group for the above would be
Whatever Group
Protocol String(10)
Server String(80),Name('web-server')
Port Long,Name('web-port')
End
TIP: The order of the fields in the group is not important, except in the case
where multiple fields have the
same external name.
TIP: For more on Creating XML that contains
attributes, see
here.
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 xml 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>
In this case the FileBoundary should be set to blank and the RecordBoundary
should be set to
data.
XML with Attributes
An alternative approach to XML 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>
Lastly, there is a special case where the xml you are
parsing looks like this;
<product>1</product>
<product>2</product>
<product>3</product>
In this case there is a list of products, where each <product> tag symbolizes
both a complete record, and the field name. Or, to describe it another way, in
this xml the File boundary AND the Record Boundary are both missing. In this
situation you call the .Load method as normal, and you must include both the
file, and record boundaries in the call, as blank strings.
Tag Case
XML is unfortunately case sensitive. This adds a layer of complexity to it since Clarion is a case-insensitive language.
Fortunately this complexity is not difficult to manage. This primary mechanism is the use of the
TagCase property. This can
be set to one of XF:CaseLower,
XF:CaseUpper, XF:CaseAsIs or
XF:CaseAny.
In most cases, for a .Load XF:CaseAny is an appropriate
option.
For a .Save it gets more complex because the case is usually determined by the program you are talking to. You can
force all the tags to be lower, or upper, case using XF:CaseLower and
XF:CaseUpper respectively. If the tags have mixed case then
your structure will need External Names on all the components, and use
XF:CaseAsIs.
Being explicit about the case before a load or save is recommended.
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.TagCase = XF:CaseAny
xml.Load(NamesQueue,'c:\temp\names.xml','table','item')
or
xml.TagCase = XF:CaseAny
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.
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
Advanced: Loading Parent and Child records at the same time
Although XML is a specification for explaining the content
of a text file, it does not dictate the structural nature of the text file. For
example the following three xml files contain the same information, but the
structure of the xml file is different. And it should be noted that these are
only three of many possible configurations.
Layout 1: In this layout the line items are included in the xml file, but are not inside the Invoice tag. Each LineItem explicitly
includes a link to the Invoice that it belongs to.
<invoice>
<number>4</number>
<customer>Fred</customer>
</invoice>
<lineitem>
<invoice>4</invoice>
<product>xFiles</product>
</lineitem>
<lineitem>
<invoice>4</invoice>
<product>NetTalk</product>
</lineitem>
Layout 2: In this layout the line items are inside the
Invoice tag, however they still explicitly link to the Invoice in question.
<invoice>
<number>4</number>
<customer>Fred</customer>
<lineitem>
<invoice>4</invoice>
<product>xFiles</product>
</lineitem>
<lineitem>
<invoice>4</invoice>
<product>NetTalk</product>
</lineitem>
</invoice>
Layout 3:
In the third layout the line items are inside the invoice,
but there is no explicit link. Rather the position of the line item, in relation
to the invoice, determines which record the line items belong to.
<invoice>
<number>4</number>
<customer>Fred</customer>
<lineitem>
<product>xFiles</product>
</lineitem>
<lineitem>
<product>NetTalk</product>
</lineitem>
</invoice>
In simple situations the Layout 1 case, and the Layout 2
case, can easily be handled using a two pass approach. Import the file twice,
once for the invoices, and once for the line items. Once the two imports are
completed all the necessary records for both tables will have been imported.
However there may be cases where the more complicated method, which is required
for Layout 3, has some advantages.
For layout three it is necessary to parse the child
records as the parent record is being parsed because otherwise there is no way
to link child records to their parent.
xFiles includes an example, called inv.app, which is in
your \clarion\3rdparty\examples\xfiles\ParentChild folder. It is recommended
that you take a moment to look at this example to see the following explanation
in action.
The basic strategy for doing a multi-level import is to
create 2, or more, xFiles objects. Each object is responsible for one target
structure. So in the layout above there is one Xfiles object for the Invoice
table (xml1), and one for the LineItems table (xml2). As xml1 reaches a lineitem
tag, it calls xml2 with that part of the xml file. Using this strategy there's
no limit to the number of levels of children in the original xml file.
xFileXML Quick Start Guide
- Creating an XML File or String
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
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,[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 attribute 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> |
| RecordBoundaryAttribute |
A fixed attribute string for the record boundary. This attribute
will be applied to all records, and should not change between records.
<?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">
See also the .UseCharSet
method, which sets an appropriate charset based on a Clarion
CHARSET:something equate. |
| 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. |
| _sFieldNameIsAttribute[x] | If set to 1 then the field will be
added as an attribute to the record boundary. See also the
SetAsAttribute method. |
| _sFieldNameAttribute[x] |
The attribute which will be added to
the _FieldName tag. If you change this be sure to change the _sFieldNameAttributeLen[x]
property as well. For example, if you wish to add the attribute
save="yes" to the field number 3 (called, say, filename) then you'd set
_sFieldNameAttribute[3] = 'save="yes"'
_sFieldNameAttributeLen[3] = len(clip(_sFieldNameAttribute[3]))
and the result would be
<filename save="yes>
whatever
</filename> |
| _sFieldNameAttributeLen[x] |
|
| 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 |
| SetAsAttribute |
This method takes the field number as a parameter. If this is called for
a field, before the call to .Save, then the field will be added to the
record boundary as an attribute. See also
Saving Fields As Attributes. |
| SaveCurrentFieldToXML |
This method is called for each field as the XML string
is created. The third parameter is the field
name. This provides you
an opportunity to alter the value in the field before it is saved to XML.
See also Formatting a field before it is
saved to XML . |
| SaveTweakFieldSettings |
Allows you to set field related properties before the
save commences. See also Properties Which
can be Set in SaveTweakFieldSettings. |
| 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. |
xFiles Templates
The Global xFiles Extension Template
In order to use xFiles, you need to add the Global Extension Template.
- 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
Generic xFiles Template (to use an xFiles object)
xFiles provides a template to make it simple to add an object to a procedure. To use the template:
- Right click on the procedure you wish to add an object
to and Choose "extensions", then press the "insert" button.
- Choose "IncludexFilesObject - Use an xFiles object"
from the 'Class xFiles - CapeSoft xFiles - Version x.xx" section.
- In the "This Object Name" field enter "xmlWriter".

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.
Export to/Import from XML Control Template
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
Some Practical Applications
Creating RSS Feed Files
- Create a window in your application and add the xFiles Global template
(if you have not done so already) and the xFiles local extension template.
You can leave the default template settings as they are.
- Your RSSFeedQueue should be of the following example structure:
- Item QUEUE,PRE()
Title STRING(252)
Description STRING(1024)
Link STRING(252)
ExtraFieldsInHere FieldTypes
END
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).
- In the ThisWindow.Init() method, set the following properties:
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>'
ThisXMLFile.RSSVersion = '2.0'
ThisXMLFile.load(RSSFeedQueue,'RSSFeedfile.xml')
- Add the necessary RSS feed items to the queue (you'll want to add them
to the front of the queue so that newest items are at the 'top of the pile'):
- Item.Title = 'My New Item'
Item.Description ='My new RSS feed description'
Item.Link = 'www.mywebsite.com\MyNewItem.htm'
Add(Item,1)
- Add a button to the window (Create RSS Feed) and in the accept event save the file:
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).
Storing Global Settings in an XML file
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)
WebSite string(252)
EmailAddress string(252)
end
FTPPostWindowThread long
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')
Creating SOAP requests
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 the optional parts have been replaced with
the name of the property you can set.
<?xml version="1.0" encoding="SaveEncoding"?>
<SOAPEnvelopeBoundary SOAPEnvelopeBoundaryAttribute>
SOAPHeader
<SOAPBodyBoundary>
<_pFileBoundary p_FileBoundaryAttribute>
<pRecordBoundary RecordBoundaryAttribute>
<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.RecordBoundaryAttribute = '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'
xml.SOAPHeader = '<soap:Header/>'
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,
XF:CaseAny and
XF:CaseAsIs.
The default is
XF:CaseAny, which means that xml files being loaded are Case
Insensitive. For a Save this implies that the case of the External Name will be
used (if it exists) and the tag is Upper Case if there is no external name.
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.
But wait, there's more. Every so often
you come across a SOAP packet that has 2 (or possibly more) parts. Something
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:Header>
<AuthHeader xmlns="urn:schemas-cardinal-com:2006:04:alaris:gateway:alarisgateway">
<ClientIdentifier>guid</ClientIdentifier>
</AuthHeader>
</soap:Header>
<soap:Body>
<QueryPatientId xmlns="urn:schemas-cardinal-com:2006:04:alaris:gateway:alarisgateway">
<deviceId>string</deviceId>
</QueryPatientId>
</soap:Body>
</soap:Envelope>
Now this SOAP Packet contains 2 parts,
a Header part and a Footer part. Which effectively means the SOAP packet
contains 2 structures (in this case 2 groups). The key to understanding how to
create this packet rests on two items;
a) See this primarily as a Multi-Part xml file, not as a SOAP packet
b) follow the directions below "
Storing
Multiple Things in the same XML file"
Aside: A small number
of servers require an empty header in order to process the packet correctly. The
SOAPHeader property has been included so that you can inject specific text (for
example
<soapenv:Header/>) between the SOAP Envelope and the SOAP Body. This
property is not formatted in any way, if you use it you will need to ensure it
is valid xml.
For completeness sake, here is the
code that creates the above packet. However you will need to read the
section below before this code will make
sense.
Structures
AuthHeader GROUP,PRE()
ClientIdentifier STRING(255),NAME('ClientIdentifier')
END
QueryPatientId GROUP,PRE()
deviceId STRING(255),NAME('deviceId')
END
Code
xml.SaveEncoding = 'utf-8'
xml.TagCase = XF:CaseAsIs
xml.RootBoundary = 'soap:Envelope'
xml.RootBoundaryAttribute = |
'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.DontCloseTags = 1
Xml.RecordBoundaryAttribute = 'xmlns="urn:schemas-cardinal-com:2006:04:alaris:gateway:alarisgateway"'
xml.save(AuthHeader,'soap:Header','AuthHeader')
xml.append = 1
xml.DontCloseTags = 0
xml.Save(QueryPatientId,'soap:Body','QueryPatientId' )
As you can see the above commands are Saving the structures to a string, not a file, and as will all strings the
result is in xml.xmldata.
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.
Formatting a field before it is saved to XML
Data in the database is often stored in a "raw" format.
Sometimes this data needs to be formatted before it can be saved. For example,
dates in a Clarion file are typically stored as a number (days since December
28, 1800), whereas in xml it would be ideal to have this formatted into a
human-readable date format.
The correct place to embed code to format the string is in
the .SaveCurrentFieldToXML method. There are two instances of this method, so
you should use the one which has p_name as one of the parameters. Inside this
method add some code to test the field name, and call the .FormatCurrentField
method with the picture. For example, in the demo application, the following
lines are used;
xmlFile.SaveCurrentFieldToXML PROCEDURE (Long p_x,Long p_DimCounter,String p_name)
CODE
if p_name = 'WAG.SALARY'
self.FormatCurrentField('@p$<<<<<<<<#.##p')
end
! Parent Call
PARENT.SaveCurrentFieldToXML (p_x,p_DimCounter,p_name)
The .FormatCurrentField method takes a standard Clarion picture as a parameter.
In some cases you will want to format the output string
completely differently to what is available via a standard clarion picture. This
is also possible, but requires slightly more code;
xmlFile.SaveCurrentFieldToXML PROCEDURE (Long p_x,Long p_DimCounter,String p_name)
text string(20)
CODE
if p_name = 'WAG.SALARY'
text = 'CASH:' & format(self.currentField,@p<<<<#.##p)
self.currentfield &= text
end
! Parent Call
PARENT.SaveCurrentFieldToXML (p_x,p_DimCounter,p_name)
First create a variable to hold the result (in this case
called TEXT). Then set text, and importantly assign self.CurrentField to point
to Text.
Tip: The p_name parameter is the tag name in the xml, not the field name in the table.
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 or string.
In order to place multiple entities in the same xml file the following basic
steps occur;
- 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
- Save the first entity as normal
xml.Save(ReportFormat ,Loc:XmlName,'Document','Record')
xml.Save(ReportFormat ,'Document','Record')
- Set the append flag so the following items are appended
xml.append = 1
- 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.Save(rrDefnFieldsLocalView,Loc:XmlName,'DefnFieldsLocal','Record')
xml.Save(rrDefnFieldsGlobalView,Loc:XmlName,'DefnFieldsGlobal','Record')
- Finally before sending the final entity, tell the object to close the root tag.
xml.DontCloseTags = 0
xml.Save(rrDefnBandControlsView,Loc:XmlName,'DefnBandControls','Record')
xml.append = 0
NOTE: This approach cannot be used if a zipped xml file is being made using
the built-in zipping classes.
Saving Fields as Attributes
Simple XML can be thought of as
<tag>data</tag>.
Despite multiple fields, and increasing levels of fields-within-fields, it
follows that relatively simple pattern.
XML however does have another trick up its sleeve. These are called
Attributes. The syntax looks something like this;
<tag attributeName="value" anotherAttributeName="value">data</tag>
xFiles reads these attributes in as data, interpreting the attribute names
into field names. From a reading-xml point of view, xFiles (and hence your
program) doesn't care if the incoming data was an attribute, or inside a
tab. You can read basic introduction to attributes
here.
Creating XML with attributes is slightly more complex than just creating
basic XML. There is no "setting" which can be applied to a data structure
which makes it an attribute, so an extra method call is required to make it
so. For example;
The following Clarion structure
Animals Queue,pre()
Type String(20)
Species String(20)
End
needs to be saved as xml, with Type as an attribute, like in this example;
<animals>
<animal type="mammal">Elephant</animal>
<animal type="reptile">Cobra</animal>
</animals>
To do this we need to use a xFileXML object, but with some code embedded
into the
.SaveTweakFieldSettings method.
xmlFile.SaveTweakFieldSettings PROCEDURE ()
CODE
self.SetAsAttribute('type')
! Parent Call
PARENT.SaveTweakFieldSettings ()
Getting the name of the attribute correct is probably the hardest part,
because it needs to match the output exactly. In other words it is case
sensitive, and should include a prefix if the output tag has a prefix. The
easiest approach is to create the XML file with all normal tags, then use
that as a reference to get the specific tag name.
An alternative is to use the field number in place of the name, but this
approach can lead to bugs if the field order in the original structure
changes.
Examples
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.
| Example |
Location & Comments |
| 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/fileexplorersp.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. |
Importing Advanced Structures
The goal of this section is to document the techniques
used to import structures that, while legal, are in some way obtuse. Various
cunning techniques are covered here, although you may not need to use any of
them in normal XML importing operations.
Importing the whole xml data record into a field in the destination structure
There are cases when you want to parse the incoming xml
into fields as normal, but you also want to store the original xml for the whole
record in a field. Indeed this may be the only field in your incoming structure.
To do this set the .StoreWholeRecord property to 1, and make a
field in your receiving structure with the same name as the Record Boundary.
Note that if the xml you are importing contains a Field with this name as well,
then you cannot make use of this option, or the whole xml will overwrite the
incoming field value.
Importing from XML where there are multiple
fields with the same name
It is legal in XML to have multiple fields (or attributes)
which are siblings of each other, with the same name. For example;
<product>
<name>Car</name>
<price type="purchase">22000</price>
<price type="lease">2000</price>
</product>
This can be imported by using a well-crafted strcture, as
well as making use of the Name attribute. The structure for the above would be;
Product Group
name String(20)
type1 String(20),name('type')
price1 Long,name('price')
type2 String(20),name('type')
price2 Long,name('price')
End
Note that in the above structure the external names are
duplicated. This is legal.
Notice also that the order of the fields is critical. Without the ability to
match exclusively on the name, xFiles will take the order of the fields into
account.
Lastly notice that the attribute comes before
the field. so the Type comes before the Price.
Classes
This lists the Classes provided by xFiles at
this time, along with a description of the functionality provided by each class.
| Class | Description |
| 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. |
| 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 |
| 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 Load is about to be done to allow the object setting to be modified before the
load code is executed. |
| SaveTweakSettings |
Called when the Save is
about to be done to allow the object setting to be modified before the save
code is executed. |
|
UseCharSet |
Sets the .Saveencoding based on a Clarion
Charset Equate. |
|
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. |
| CleanFileName |
Called when a file is saved to ensure there are no invalid characters in the file name. |
| xFileXML Properties |
|
dontReplaceColons |
Replaces colons with full stops when writing
prefixes to the file (on by default) |
| IgnoreGroupTags |
Ignores groupings when loading and saving. |
| 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 |
| CRLF |
A string containing the line-ending to
place after each tab. This makes the xml more readable, but at the cost of
some extra characters in the xml file. Set to 0 to suppress indenting. The
default value is 2. |
| IndentBy |
the number of spaces (default = 2) to
indent rows by to make the xml more readable. Set to 0 to minimize the size
of the xml. |
|
_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 |
RecordBoundaryAttribute
(this used to be called _pRecordBoundaryAttribute before version 2.28) |
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 ,XF:CaseUpper, XF:CaseAny or XF:CaseAsIs.
The default is XF:CaseAny, which means that xml files being Loaded are Case
Insensitive. For a Save this implies that the case of the External Name will
be used (if it exists) and the tag is Upper Case if there is no external
name. |
| UpdateAsWhole |
If an incoming record updates an existing
record, then assume the incoming record overwrites _all_ the fields of the
existing record. Note this mode is not supported if the file has memo or
blob fields. |
|
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 |
| dontCleanFileName |
If this is set the CleanFileName method will
not check for invalid characters when saving the XML file. This property is
not normally used. |
| StoreWholeRecord |
If set to true, and there is a field in
the structure with the same name as the record boundary, then the xml for
the whole record is placed in that field. |
| 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 Class Methods

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 the data is copied from
the xFilesXML object to the passed group/queue.
If p_Direction is 1 then records are copied from
the passed queue or group to the xFilesXML
object. |
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 |
myQueue queue
from string(80)
to string(80)
end
xmlFileName string(260)
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. |
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 |
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:
| Parameter |
Description |
*Queue p_Queue or
*Group p_Group or
*File p_File or
*View p_View
|
The label of the queue, file, view or group that contains the data to be saved to the
XML file or string. |
| string p_FileName |
The name of the XML file to store the data in. If this file does not exist
it will be created. If this parameter is omitted completely then the XML
will be written into a string. This string is accessible after the call to
.Save in the object's XmlData property. The length of the string is in the XmlDataLen
property. |
| <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
Save by passing the data structure and file name |
myQueue queue
from string(80)
to string(80)
end
xmlFileName string(260)
CODE
xmlFileName = 'myXmlFile.xml'
thisFileXML.Save(myQueue, xmlFileName)
|
See Also:
xFileXML.Load(),
xFileXML.Init()

xFileXML Advanced Methods
Generic File Loading and Saving
xFileXML.SaveBinData (<string fileName>)
Saves the current contents of the
binData property to disk using the either the
file name passed using the fileName parameter, or the file name set when the
Init() method of the object was called. This method along with the
LoadBinData() provides generic reading and writing
of files to and from memory. This method does not parse the string in any way
and will not load the data into a queue, group or file. Use the
Load() method to load XML files into data structures. This method essentially exposes
the generic file handling provided by the parent xFileBinary class, which
provides file handling (reading and writing) along with on the fly
compress/decompression etc..
When used in conjunction with the
.saveToString
property this can be used to customise the XML produced before
writing it to disk by calling SaveBinData.
Note: To
create a ZIP compressed file containing the data in the .binData
string, set the ZipUseZip property to 1 before calling the SaveBinData. This same
technique can be use to ZIP compress and decompress XML files on-the-fly using
the Load() and
Save() methods.
Parameters
| Parameter |
Description |
| string fileName |
An optional parameter that specifies the name of the
file to save. This must be passed if the Init() method has not been called
to set the file name. |
| |
|
Return Values
If the call fails it returns zero and the
ErrorTrap method of the class is called with
the error details. You can add code to the ErrorTrap method
to display errors, log them to debug output etc.
Examples
| Example 1 -
Saving data from the binData string to disk |
code
if not
xFileXml.binData &= null
Dispose(xFileXml.binData)
end
xFileXml.binData &= new string(myXmlSize)
xFileXml.binDataLen = myXmlSize
xFileXml.binData = Clip(string1) &
Clip(string2)
xFileXml.SaveBinData('myfileName.xml')
|
| |
See Also
LoadBinData(),
Save(),
Load(), binData, binDataLen, saveToString, loadFromString


xFileXML.LoadBinData (<string
fileName>)
Loads a string directly into the binData
property of the class with doing any parsing or handling of the contents of the
file. When this method is called the .binData
property of the class is receives the contents of the file (memory allocation
and disposable is handled by the class). In addition the .binDataLen property of
the class is set to the size of the file loaded (in bytes).The .binData property
is a string.
This method along with
SaveBinData() expose
generic file reading and writing using the xFileXML class. This can be useful
when used with the .saveToString and .loadFromString
properties. The data can be loaded and manipulated manually before the
Load() and
Save() methods are called
to load (or save) the data to and from memory.
Note: To
load a ZIP compressed file, set the _ZipUseZip property to 1 before calling the
LoadBinData() method. This same
technique can be use to ZIP compress and decompress XML files on-the-fly using
the Load() and Save() methods.
Parameters
| Parameter |
Description |
| string fileName |
An optional parameter that specifies the name of the
file to load. This must be passed if the Init() method has not been called
to set the file name. |
| |
|
Return Values
If the call fails it returns zero and the
ErrorTrap method of the class is called with
the error details. You can add code to the ErrorTrap method
to display a message, handle the error, log error etc.
Examples
| Example 1 -
Load data from the to disk to the xFileXML.binData string |
code xFileXml.
LoadBinData('myfileName.xml')
! the .binData now contains the contents of the file |
| |
See Also
SaveBinData(),Save(),Load(), binData, binDataLen,
saveToString, loadFromString


XML file modification and settings
xFileXML.CreateHeader ()
Sets the header for the XML file and adds
it to the .binData string. This is called before
data is added to the XML file. The string created is a standard XML header such
as:
'<?xml version="1.0"?><13,10>'
Note: If
the .saveEncoding property is set then this
string includes the encoding for the file. The .binData
property is set to the string created by this method and a carriage
return, linefeed pair is added to the end of the header string (ASCII 13, 10) as
indicated in the code snippet above. The binDataLen property is set to the
length of the .binData string property (the
number of bytes in the header).
Parameters
None
Return Values
None
See Also
CreateFooter()


xFileXML.CreateFooter()
Creates the footer for the XML file. This
is simply the closing tag for the file, such as the file boundary (see the ._pFileBoundary
property). In general this method does not need to be overridden unless a
custom header has been created or additional wrapper tags have been added.
Note:
The footer is appended to the .binData string and
the .binDataLen property incremented by the number of bytes added.
Parameters
None
Return Values
None
See Also
CreateHeader()


xFileXML.LoadTweakSettings()
A purely virtual method that allows the
programmer to override the settings before the Load() method actually loads and
parses the XML file. Use this for setting the file or record boundaries or other
settings that need to be customised to load a specific file.
Parameters
None
Return Values
None
See Also
SaveTweakSettings()


xFileXML.SaveTweakSettings()
A purely virtual method that allows the
programmer to override the settings before the Save() method actually creates
the XML file. Use this for setting the file or record boundaries or other
settings that need to be customised before the XML is created and saved to disk
or memory.
Parameters
None
Return Values
None
See Also
LoadTweakSettings()
SaveTweakSettings()


xFileXML.UseCharset(Long
p_CharSet)
Sets the .SaveEncoding property based on
a Clarion charset equate.
Parameters
| Parameter |
Description |
| long p_Charset |
A standard Clarion Charset equate |
Return Values
None


Record handling and management


xFileXMLGetValue (string
p_Field, long p_dim = 0)
Retrieves the value of a field when
passed the name of the field. For multi dimensional fields (Clarion 6 only) the
second parameter allows the dimension to be retrieved to be specified. Note that
the Init()() method must have been called to specify
the data structure that the xFilesXML object is manipulating before this method
is called.
Note:
This method is thread safe and wraps access to queues in a critical section. All
the methods in xFiles are built to ensure thread safe access to data (including
global, unthreaded data)
Parameters
| Parameter |
Description |
| string p_Field |
A string that contains the name of the field to be fetched. |
| long p_dim |
An optional parameter that specifies
which dimension to fetch for multi dimensioned fields. Supported in Clarion 6 only |
Return Values
The value of the field is returned as an
ANY variable. If the field is not found an empty string is returned.
See Also
SetValue()


xFileXMLSetValue ( string p_Field, string p_Value, long p_dim = 0)
Sets the values of a specified field.
Works for queues, groups and files. Note that the
Init method must have been called
to specify the data structure that the xFilesXML object is manipulating before
this method is called.
Note:
This method is thread safe and wraps access to queues in a critical section. All
the methods in xFiles are built to ensure thread safe access to data (including
global, unthreaded data).
Parameters
| Parameter |
Description |
| string p_Field |
A string that contains the name of the field to be to be set. |
| string p_Value |
A string that contains the value to set the field to |
| long p_dim |
An optional parameter that specifies
which dimension to set for multi dimensioned fields. Supported in Clarion 6 only |
Return Values
Returns zero for success and -1 if the field is note found.
See Also
GetValue()


xFileXML.InsertFileRecord
()
This method adds the contents of the
current file buffer as a new record in the file that is associated with xFiles.
This method is not generally used directly.
Note:
The Load(),
Save() or
Init() method must
be called before this method is used in order for the xFilesXML object to be
associated with a particular data structure.
Note:
This method only supports files and does not update any relationships.
Parameters
None
Return Values
None
See Also
UpdateFileRecord()


xFileXML.UpdateFileRecord
()
This method updates the current file
record with the contents of the current file buffer. This method is not
generally used directly.
Note:
The Load(),
Save() or
Init() method must
be called before this method is used in order for the xFilesXML object to be
associated with a particular data structure.
Note:
This method only supports files and does not update any relationships.
Parameters
None
Return Values
None
See Also
InsertFileRecord()


xFileXML.RecordCount
()
Returns the number of records in the File
or Queue that is associated with the xFiles object.
Note:
The Load(),
Save() or
Init() method must
be called before this method is used in order for the xFilesXML object to be
associated with a particular data structure.
Parameters
None
Return Values
The number of records in the Queue or
File that is currently associated with the xFilesXML object.
See Also


xFileXML.FreeFileData
()
Deletes all records in the File
associated with this object. All records are removed, however no relationships
are updated. This method is not generally called directly. This method only
applies if the xFilesXML object is being used with a File.
Note:
The Load(),
Save() or
Init() method must
be called before this method is used in order for the xFilesXML object to be
associated with a particular data structure.
Parameters
None
Return Values
The number of records in the Queue or
File that is currently associated with the xFilesXML object.
See Also


xFileXML.FreeGroupData
()
Clears all fields in the group that is
associated with the xFileXML object. This method only applies if the xFilesXML
object is being used with a Group.
Note:
The Load(),
Save() or
Init() method must
be called before this method is used in order for the xFilesXML object to be
associated with a particular data structure.
Parameters
None
Return Values
None.
See Also


xFileXML.FreeQueueData
()
Deletes all records in the Queue
associated with this object. This method only applies if the xFilesXML object is
being used with a Queue.
Note:
The Load(),
Save() or
Init() method must
be called before this method is used in order for the xFilesXML object to be
associated with a particular data structure.
Parameters
None.
Return Values
None.
See Also


xFileXML.AddOldField (string p_OldFieldName, string p_InFilePos), long
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. You should embed your calls to this method in the
LoadAllOldFields procedure, after the parent call, as this gets call when Load is called.
Parameters
| Parameter |
Description |
| string p_OldFieldName |
A string that contains the odl name of the field |
| string p_InFilePos |
The position in the file record at which this field resides. |
A typical call to this procedure would look something like this:
MyXML.AddOldField('OldFieldName', where(OldFieldFile.Record, OlfFieldFile.OldFieldName))
Return Values
Returns 0 if adding this old fieldname was successful. Will only fail if there is no more space for extra fieldnames. The maximum is XF:MaxFields.
See Also
LoadAllOldFields()

xFileXML.LoadAllOldFields ()
This is called when Load is called. Embed your calls to
AddOldField() here, after the parent call. Be sure to embed after the parent call as the parent call clears all
the old fieldnames (used for the previous load).
Parameters
None.
Return Values
None.
See Also
AddOldField()


xFileXML.CleanFileName
(string p_Filename, long p_flag=0)
This is called when Load is called to
ensure that the file name has no invalid characters. ASCII control characters
with values below 21 are replaced by spaces and characters that are illegal in
Windows file names (* / \ ? < > :) are removed. Use this method to remove all
non-legal characters from a string so that it can be used in a file name. Note
that this method removes backslashes ( \ ) so it should be used on just the file
name, but NOT the path.
! to use it on a Path set the flag to XF:ALLOWBACKSLASH this flag also
implicitly allows a : in character 2 (for example 'c:\temp.xml'). Illegal
characters are replaced with a space.
To disable this behaviour set the xFileXML.dontCleanFileName
property to 1.
Parameters
p_FileName
The name of the file to be saved, excludes the
path to the file (unless the p_flag parameter is set to XF:ALLOWBACKSLASH to
allow backslashes and handle paths). For example 'settings.xml'.
p_flag
This is a flag to override the default
behaviour and allow back slashes. If this contains XF:ALLOWBACKSLASH then
backslashes are allowed. Use this to allow paths to be checked.
Return Values
Returns the valid file name, after
illegal characters have been removed.


xFileXML Property Reference
These are some of the properties of the xFileXML class that you might find useful
to set directly.
|
dontReplaceColons |
long |
By default xFiles replaces colons with full stops when writing prefixes
to the file. Colons are not valid in the XML tags except for namespaces.
Set the dontReplaceColons property to 1 to not replace colons
in the XML file with full stops and zero to leave them as colons. This does
not effect the operation of xFiles, however setting
dontReplaceColons to 1 will result in invalid XML that is not viewable in XML viewers and parsers.
|
|
IgnoreGroupTags |
long |
Saving: If this property is set then
Groupings of fields in your clarion structure is ignored. The structure is
saved as if the structure contains no groups.
Loading: If this property is set, then xml fields are
imported by name, regardless of their grouping (or lack of grouping) in the
xml. In other words the import will pay no attention to grouping in the xml,
or grouping in the clarion structure. If the xml however does contain
groups, and inside those groups are duplicated field names, then the import
will be unable to distinguish the fields.
|
|
loadFields |
long |
This allows the number of fields to be loaded to be different from
the number of fields in the queue, for example the first 5 fields might
contain data, and the second 5 might be for temporary data, or the result
calculations that aren't stored in the XML file. Setting
loadFields to 5 will load the first 5 fields of the queue from the XML file, even if
there are ten fields in the queue or file. See the
Load() method. |
|
saveFields |
long |
The saveFields property has the same function as the
loadFields property,
except the it determines how many fields are saved in the XML file rather
than how many fields are loaded from it.
|
|
copyFields |
long |
The number of fields to copy between the two data
structures when calling the Copy() method. Allows the number of fields being
used to be limited. |
| addFields |
long |
The number of fields to add when inserting a record into the queue by calling
the AddRecord() method. |
|
dontLoadLastFields |
long |
Performs the same function as the loadFields property, however it
allows the number of fields to be excluded to be specified from the last
field in the queue, rather than specifying the number of fields to be included
from the first field in the queue (which is what loadFields does).
|
|
dontCopyLastFields |
long |
The same as the dontLoadLastFields property, except for copying from one
queue to another using the Copy() method.
|
| dontAddLastFields
|
long |
Performs the same function as
dontCopyLastFields, except for the
AddRecord() method - it limits the number of fields that are added when inserting a
record into the queue.
|
|
columnDisabled |
byte, dim(XF:MaxFields) |
This is an array map of the columns that allows a column to be enabled(0)
or disabled(1). All columns are enabled by default, but you can disable
individual columns by setting the byte in the map for that particular
column. E.g. (to disable column 4):
ThisFileXML.ColumnDisabled[4] = 1
|
|
_pFileBoundary |
pString(252) |
This is the boundary of the queue, file or group. For a group, this would
normally be Group, for a file, file, for a queue, queue, for an RSS feed,
channel, etc. ThisFileXML._pFileBoundary
= 'channel'
|
|
_pRecordBoundary |
pString(252) |
This is the boundary between each record in the queue
of file being loaded. This allows the tag used as the record boundary to be specified.
|
| binData |
&string |
|
The actual internal data store for loaded files.
Memory allocation and disposal is handled by the class.
When an XML file is loaded the data is loaded into this buffer and the size
of the loaded data is stored in the binDataLen property. Generally this
property does not need to be manipulated directly unless the LoadBinData and
SaveBinData methods are being used to write this directly to disk (which
allows generic file reading and writing as well as customisation of the data
being read and written).
|
| binDataLen |
long |
The size of the
binData property (in
bytes). This is set automatically when an XML file is loaded from disk.
|
| xmlData |
&string |
A string that is populated with the XML by the
Save() method, if
saveToString
is set to 1. This allows XML to
be "saved" into memory rather than written to disk directly.
See Also
Properties: loadFromString,
saveToString
Methods: Load(),
Save()
|
| xmlDataLen |
long |
The length (in bytes) of the
xmlData string property.
The xmlData
property is used for loading and saving XML to and from memory rather than from disk.
See Also
Properties:
loadFromString,
saveToString
Methods: Load(),
Save() |
|
saveToString |
pString(252) |
When this property is set the Save() method saves the
XML data in the xmlData string instead of
writing it to disk. The Save() method can be passed a blank file name if
this is set, as the file name parameter is not used.
See Also
Save(),
loadFromString |
|
TagCase |
pString(252) |
The field name tags are automatically detected for you by the xFiles
class. In some XML situations the case of these tags may be important. This
property gives you control over the case used. This property defaults
to XF:CaseAny. Other options are
XF:CaseLower, XF:CaseUpper and XF:CaseAsIs. In order to have mixed case tags, the
Name property for each field in the group/file/queue must be set.
This property only applied to field-level tags, not header or boundary tags.
The default is XF:CaseAny, which means that xml files being loaded are Case
Insensitive. For a Save this implies that the case of the External Name will
be used (if it exists) and the tag is Upper Case if there is no external
name.
See Also
Creating SOAP requests |
|
loadFromString |
pString(252) |
|
When this property is set the Load() method loads the
XML data in the xmlData
string instead of loading it from disk.
This property does not need to be set manually any longer as the Load()
method now directly supports passing a string containing the XML to loading
into the passed data structure.
See Also
Load(),
Save(),
saveToString
|
|
omitXMLHeader |
long |
Omits the first tag in the XML file. See
CreateHeader and
CreateFooter for more
information on the header and footer tags.
|
|
dontCleanFileName |
long |
If set to 1 the CleanFileName method will not remove
invalid characters from the file name, but simply return it as-in. This
should not be used in normal circumstances. |
|
StoreWholeRecord |
long |
If this property is set to true, and a field in the
structure exists, with the same name (or external name) as the record
boundary, then the xml for the whole record will be stored "as is" in this
field.
|
xFileLinkDLL Methods - Runtime DLL Loading
xFileLinkDLL.LinkDLLFunction
(string p_DLLName, string
p_FunctionName, *long p_fpFunction)
This method loads a function from a DLL
when passed the name of the DLL and the name of the function to locate. If the
DLL has not already been loaded it loads the DLL. The address of the function is
located and stored in the passed p_fpFunction parameter .
Parameters
| Parameter |
Description |
| string p_DLLName |
A string containing the name of the DLL that contains
the function to load. If this library has not already been loaded then the
method will load it before locating the required function address. |
| string
p_FunctionName |
The name of the function to locate in the library. |
| *long
p_fpFunction |
A long that will receive the address of the function in the library. |
Return Values
Returns zero for success, or an error
code if it fails.
Examples
See the "Runtime DLL Loading QuickStart
Guide" for a full example and how to declare and use the addresses returned.
| Example 1 -
Load a function called 'unzOpen' from a DLL called
'zip.dll' |
code ret = xLinkDLL.LinkDLLFunction ('zip.dll',
'unzOpen', fp_unzOpen) |
| |
See Also
DontDisplayMessages
These are some of the properties of the xFileLinkDLL class that you might find useful
to set directly.
|
dontDisplayMessages |
long |
This option ensures that an error message is not displayed if a DLL fails
to load or a function cannot be located. Set this option
to 1 to not displayed error messages. The .ErrorTrap method will still be
called with the message details when this is set to 1.
|
FAQ
xFileXML
- I declare the object and call Load/Save but nothing happens.
xFiles provides two ways to handle loading and saving of XML files:
- Without needing the Init method, you can
call Load and Save
and pass the data structure and file name directly to the load and save
methods:
xFileXML.Load(p_Queue,
fileName)
xFileXML.Save(p_Queue, fileName)
- By calling Init to set the data structure
to use and the file name, then calling Load
and Save:
xFileXML.Init(p_Queue,
fileName) !
Call Init to set which data structure and file to use
xFileXML.Load()
xFileXML.Save()
You don't need to use the second method and 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.
- Is there any way to change the tag itself when writing out an XML file
from a browse?
I see that I can format or change the contents but not the
tag itself.
Yes, there is a way. In the SaveCurrentFieldToXML method you can change
the outgoing name of the field. To do this you do something like this;
In this method
xFileXML.SaveCurrentFieldToXML PROCEDURE (Long p_x,Long p_DimCounter,String p_name)
[aside – make sure it's this one, there are two with the name SaveCurrentFieldToXML
]
case p_name
of 'REQUESTEDACTION'
self._sFieldName[x] = 'REQUESTTYPE'
end
This goes before the parent call.
If you were using this embed to format the contents of the field as
well, then do this before that code, and in that code check self._sFieldName[x]
instead of p_name because otherwise the first time the p_name will be
wrong.
Clarion 5 and Clarion 5.5 Support Limitations
Clarion5
Note: Clarion 5 is no longer supported directly by xFiles - the Clarion 5 limitations here are listed for historical reasons.
The following features are not available in the Clarion 5 version of xFiles
- In xFiles.Inc, the Equate XF:MaxFields must be reduced from the default (1024) to 256 (or lower).
- Saving a VIEW to an XML file is not possible in Clarion 5.
- If you are saving a FILE you must set the .R property to the file record before the call to SAVE or INIT. For example
xml.R &= cus:record
- And all the Clarion 5.5 Limitations listed below.
Clarion 5.5 Support Limitations
The following features are not available in the Clarion 5.5 version of xFiles
- Nested Groups are not supported
- Arrays are not supported
Support
Your questions, comments
and suggestions are welcome. See our web page (
www.capesoft.com)
for new versions. You can also contact us in one of the following ways:
| CapeSoft Support |
| Email |
|
| Telephone |
+27 21 715 4000 |
| Fax |
+27 21 715 2535 |
| Post |
PO Box 511, Plumstead, 7801, Cape Town, South Africa
|
xFiles may be purchased for $59 from:
| CapeSoft Sales |
| Web |
www.capesoft.com |
| Email |
 |
| Telephone |
+27 21 715 4000 |
| Fax |
+27 21 715 2535 |
| Post |
PO Box 511, Plumstead, 7801, Cape Town, South Africa |
Installation
To download the latest installation please visit
the CapeSoft
Downloads page.
To install extract the Installation Program from the SAF file
using the free CapeSoft Safe Reader (download for free from
http://www.capesoft.com/utilities/Safe/safereader.htm).
Run the Installation Program for your version of Clarion.
Distribution
xFiles ships as source so it is compiled into the application and
there are no additional files needed for distribution. There are no runtime
royalties for using xFiles. Also see the
License & Copyright
section for more information.
License & Copyright
This template is copyright © 2005-2012 by CapeSoft Software.
None of the included files may be distributed. Your programs
which use xFiles can be distributed without any xFiles royalties.
Each developer needs his own license to use xFiles. (Need to
buy
more licenses?)
This product is provided as-is. Use it entirely at your own risk. Use of this
product implies your acceptance of this, along with the recognition of the
copyright stated above. In no way will CapeSoft Software, their
employees or affiliates be liable in any way for any damages or business losses you may
incur as a direct or indirect result of using this product
Version History
Download latest version
here
Version 2.28 (24 January 2012)
- Added support for Attributes when creating XML.
- Fix: Possible GPF when used in Multi-DLL mode with BoTran.
Version 2.27 (11 October 2011)
- Fix: Calling Save on a File, with Strings set to CData did not correctly
recognize a Group as a Group.
Version 2.26 (6 Sept 2011)
- Corrected examples with missing files.
Version 2.25 (20 July 2011)
- Support for attributes quoted with a single-quote added.
Version 2.24 (28 June 2011)
- Support for ColumnDisabled property added to .Load method.
Version 2.23 (4 May 2011)
- Tweak to template to support xFile objects generated
into Source procedures in Clarion 8.
Version 2.22 (24 March 2011)
- Added .CRLF property so that alternate line endings
can be used. Default is CR/LF (ie char 13, followed by char 10). Use this in
conjunction with the IndentBy property to minimize the size of the xml.
Version 2.21 (24 March 2011)
- Add new method, SaveCurrentFieldToXML with name
parameter. Makes custom formatting of fields easier if you have the name.
- Add new method FormatCurrentField to simplify simple
formatting of a current field.
- Added section to the docs:
Formatting a field before it is saved to XML
Version 2.20
- Added new method, UseCharSet which sets the .SaveEncoding
property based on a Clarion Charset.
- .RSSVersion string extended from 10, to 252
characters
Version 2.19
- Added support for auto closed, empty tags, when doing
a 'match by number'.
Version 2.18
- Fixed place where dontReplaceColons property was not
being respected.
- Added PROC attribute to Save method declaration
Version 2.17 (24 January 2011)
- Added XF:CaseAny equate
- Set default of TagCase property to XF:CaseAny
Version 2.16 (19 January 2011)
- Fixed regression with errant SOAP boundary appearing
in non-soap xml.
Version 2.15 (14 January 2011)
- Added support for SOAPHeader
property.
Version 2.14 (1 December 2010)
- Prototype for Copy method changed to
explicitly take both source and destination structures. This avoids possible
thread problem with global, unthreaded, objects.
- .TagCase property can be set to
XF:CaseAsIs for Loading. If set, then all structure
external names need to be set specifically.
Version 2.13 (27 November 2010)
- SOAPEnvelopeBoundaryAttribute lengthened from 252 to
1024 characters.
Version 2.12 (15 November 2010)
- fixed regression in string length of encoded strings
when converting & to &
Version 2.11 (26 September 2010)
- Fixed bug with encoding of &, < and > in xml that
wasn't encoded any other way.
Version 2.10 (24 August 2010)
- Fixed regression with records being filtered in
ValidateRecord
Version 2.09 (4 August 2010)
- Added .PrefixChar property (defaults to :)
Version 2.08 (23 July 2010)
- Add EndRecord method - allows you to embed strings,
when saving, right before the end of a record.
- AddString method - allows you to inject a custom
string into the xml stream when saving.
Version 2.07 (12 July 2010)
- Fix possible GPF when saving large fields (> 1 MB).
- Optimized encoding of &, < and > characters.
Version 2.06 (18 May 2010)
- Fix GPF in AssignField. If CurrentFieldNumber was 0 , then it was using
that to check the GroupLen array.
Version 2.05 (2 April 2010)
- ParseAttr method saves, and restores currentTag
property.
- Autoclosing a tag while in a record refined.
Version 2.04 (March 2010)
- CurrentTag property set when parsing attributes on a
.Load
- added support for <record attr="whatever" /><record
attr="something" /> styled xml
- added autoCloseTags property for loading invalid xml.
Version 2.03 (1 March 2010)
- Updated Demo app, modernising calls in embeds to
.Load and .Save
- Fixed bug where closing tag might be truncated if
indent was <> 0 at that point.
Version 2.02 (17 February 2010)
- Added IndentBy property. Set to 2 by default. Set to
0 to suppress all indenting, before the call to .Save.
Version 2.00 (5 January 2010)
- Fixed another problem with groups in a VIEW
Version 1.99 (11 December 2009)
- Fixed problem detecting GROUPs in Views with a JOIN
- Fixed problem where SetFieldPointer method could
enter infinite loop
- Fixed problem where IgnoreGroups property was on.
Version 1.98
- Added support for structures that contain a field
with the same name as the record.
- Added support for multiple fields, with the same
name, in the same structure.
- Added new section to the docs called
Importing Advanced Structures.
- Added StoreWholeRecord
property.
- Fixed: Bug closing group structures where last field
in group was disabled, or an Over.
Version 1.97
- fixed bug where xml with no encoding specified was
assumed to be utf. This affected extended character sets that were encoded,
but used a scheme other than utf-8.
Version 1.96
- fixed bug where attribute started a new line
- fixed bug when loading memos and blobs
- tweaked code in decode method for Clarion 5.5 and
earlier support.
- Change to Copy method to allow for the case where the
file is closed.
- fixed bug in complex structure save where text was
appended.
Version 1.95
- Added support for one complex structure inside
another. For example a queue of Queues, a queue of Files and so on. See QinQ
example for hints on the way to do it.
Version 1.94 (20 August 2009)
- Fixed regression with dimensions being over-detected.
Version 1.93 (13 August 2009)
- Added automatic detection of dimensioned fields to
Groups and Queues for Load and Save. Only C6 and higher can detect
automatically, C5 and C5.5 need to set _Dimension[FieldNumber] specifically
in SaveTweakFieldSettngs.
Version 1.92 (28 July 2009)
- added support for " and ' encoded
characters.
- added support for group structures that contain
attributes, but no data, and end with the abbreviated close tag.
- extended example added in version 1.91to handle
cnumber field.
Version 1.91 (21 July 2009)
- Added support for xml where the record boundary
contains data. See ParentChild example, Example2 procedure.
Version 1.90 (15 July 2009)
- Fixed regression with CurrentTag property missing.
- Corrected ParentChild example which was missing the
example xml file.
Version 1.89 (13 July 2009)
- Fixed bug where SendToString property was not
explicitly being set to 0 when .Save method (to file) was called.
- Added UpdateAsWhole property for updating incoming
records. Note that if the file has memos then this mode is not supported.
Version 1.88 (18 May 2009)
- Fixed bug where updating records that contain arrays
- save Buffer size was calculated incorrectly.
Version 1.87 (6 May 2009)
- Better support for arrays in Queues and arrays in
Groups. However note that you need to manually set
xml._Dimension[fieldnumber] = xxx
before calling Load or Save.
xxx is the size of the dimensioned field (i.e. the number of elements in the
array).
Version 1.86 (17 April 2009)
- Added support for decoding xml that has no File
boundary AND no Record boundary. In this case each tag triggers a save to
the File, or Queue.
- New example, "ParentChild" included to show how child
records inside a parent xml can be parsed using a second xFiles object.
Version 1.85 (4 April 2009)
- AssignField method (used when loading) now takes decoded string rather than encoded boundaries into BinData.
This allows for much easier control over altering (formatting / deformatting
etc) incoming values before they are assigned to the Group, Queue or Field
field.
Version 1.84 (23 March 2009)
- fixed bug where number of fields in group was
inaccurate if group contained fields with no label.
- fixed bug where groups-in-groups could fail where
group tags were case sensitive.
- Calling ._close after an error resulted in the error
code being cleared.
Version 1.83 (12 March 2009)
- Fixed regression where multiple root boundary tags were included in multi-part xml docs.
Version 1.82 (10 March 2009)
- Fixed possible memory lead when saving xml into a string.
- Fixed possible "hang" where an error
occurs during a load, leaving the CriticalSection in an unreleased state
- Corrected problem with SOAP header
being omitted if OmitXMLHeader was set when calling Save. (Thanks to Sebastian Arribas.)
- Added AddQueueRecord method. (Virtual method called before a record is added to the Queue)
Version 1.81 (26 February 2009)
- Extended
Append to support Xml-To-Strings.
Version 1.80 (19 February 2009)
Version 1.78 Beta (10 November 2008)
- Clarion 7 compatible install.
- Class - don't write the record boundary if there is none.
- Template - change to the tpw (fix Methods list to '' when finished generating the list).
Version 1.77 Beta (23 September 2008)
- Fixed extra space at the end of RootBoundary and SOAPBoundary tags.
- More template updates to prevent dropped objects.
- Import/Export Control template updated to support Clarion 5.
- Table, and Row boundaries added to the Import/Export Control template.
Version 1.76 Beta (12 September 2008)
- Documented
limitations for Clarion 5, and Clarion 5.5
- Improved support for Clarion 5 File-To-XML
- Added small FileDump example.
- Template change to try and avoid orphaned methods.
Version 1.75 Beta (10 July 2008)
- fixed bug in FileBinary.Init method that could truncate file names. (Thanks to Benjamin Krajmalnik)
- improved support for groups, where the
Clarion group is a superset of the XML group, of the xml file being loaded.
Version 1.74 Beta (19 June 2008)
- Added template option to both global and local templates;
"Update File on Import if record already exists".
- fixed bug with importing records if records already exist.
- improved error information when errors occur while loading an XML file.
- improved speed when importing records, and the records exist, and the file has no memos or blobs.
Version 1.73 Beta (16 June 2008)
- fixed possible GPF when loading/saving XML from a string (not a file).
- improved the RemovePrefix support a
lot. Specifically if the .RemoveProperty is set then prefixes in the XML are
now ignored, INCLUDING prefixes in the FileBoundary and RecordBoundary. In
additional prefixes in the .RecordBoundary and .FileBoundary properties are
also removed.
Version 1.72 Beta (12 June 2008)
- fixed regression: DontCleanFileName property was in the wrong class.
Version 1.71 Beta (11 June 2008)
- fixed bug which hindered loading of CDATA strings > 1024 characters
- improved group support when saving and loading File, View and Queue structures
- explicitly cleared various properties
on load & save, making multiple use of the same object better.
- handles .\ and ..\ in path better when writing in append mode.wc o:\cl
- Added new property
IgnoreGroupTags. Set this before saving
to NOT write out the group tags around grouped fields.
Set this before loading to allow ungrouped XML fields to be loaded into a
structure - even if they are grouped in your clarion layout. If the XML
fields are grouped then the fields will still load, however there may be
complications if you have duplicate field names in the xml.
Version 1.70 Beta (19 May 2008)
- Fix: Allowed more characters as legal in CleanFileName method
- Fix: Handled case in Load where record boundary is a subset of a field label.
Version 1.69 Beta (13 May 2008)
- support for auto-closed tags in RSS feed
- Added support for
loading xml files that contain comment
Version 1.68 Beta (2 April 2008)
-
Added support for nested groups for both load and save.
-
added "standalone" property which can be se to "yes" or
"no" as desired. For example;
<?xml version="1.0" standalone="yes">
-
Fixed regression in XML Settings class. FileBoundary and
RecordBoundary attributes now set correctly.
-
Fixed over-zealous error reporting in _close method.
Closing an already closed file no longer results in an error.
-
New Jump-Start section added to the docs -
Creating an XML File or String
Version 1.67 Beta (14 March 2008)
-
Fixed regression with Load methods not using default
FileBoundary and RecordBoundary properties.
VERY IMPORTANT NOTE: These
properties are now no longer set to default values by the INIT method. If
you are using the (obsolete) Load mechanism of
xml.Init()
xml.Load()
Then you will need to set these two properties before the call to .Load.
(Before or after .Init is fine.) EG
self._pRecordBoundary = 'item' ! or 'data'
self._pFileBoundary = 'queue' ! or 'file', or 'view', or 'group'
As an alternative use the new forms of .Load and .Save.
- Added extra Save methods to support setting the FileBoundary and RecordBoundary in the
Save command.
Version 1.66 Beta ( 14 March 2008)
Version 1.65 Beta (29 Feb 2008)
- Added two new procedures, AddOldField and
LoadAllOldFields. This
allows you to change a table, view, group or queue field name and still import and XML file using the old field name.
- Some more minor bug fixes.
Version 1.64 Beta (20 Feb 2008)
- Changed: Remove all Stop() message for
API failures. These are handled by ErrorTrap (and logged if logging is
enabled) and the application should choose the desired behaviour when an error occurs.
- Added: Additional file handling for
opening files that are not already open when the Load(), Save() and Copy()
methods are used. The file maintains it's state (if a closed file is opened
it is closed when the method is complete).
- Added: Additional features specific to
CapeSoft Email Server in Service mode. This release is required for the
source code version of Capesoft Email Server 3.83 and later.
Version 1.63 Beta (15 Feb 2008)
- Fix: Supports <tag/> syntax as well as <tag /> syntax.
- Add: Any attributes in the Record Boundary are now parsed
into fields as if they were separate tags. 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>
- General: cleaned code to remove out-of-date comments, and
old, commented-out code.
Version 1.62 Beta (5 November 2007)
- If RootBoundary set during Load, then root boundary attributes loaded into
RootBoundaryAttribute property.
Version 1.61 Beta (26 October 2007)
- Add: Ability to store multiple things (Groups, Queues, Files, Views) in a
single XML file. See Storing multiple
things in the same XML file for more details.
- Add: Files which are part of the View are automatically Bound.
- Fix:A GPF could occur if using the .Save(View) method, and
the table could not be opened.
- Fix: Dict example was missing Wages.Tps file.
- Fix: Saving a View would fail if the view had a prop:filter
- Fix: Tag names for blobs & memos were not clipped
- Fix: If the "simple" form of the view was coded (i.e. with no projected
fields) then xFiles would GPF if the file structure contained over fields.
- Fix: Loading file boundary attribute was broken if attribute did not exist.
Version 1.60 Beta (13 September 2007)
- Added ability so save VIEWS to an XML file, or string.
- Added .ValidateRecord method to allow client-side filtering of records being saved, or loaded.
- Added ability to ignore attributes on a record boundary.
(Similar to the feature done for 1.51 for the file boundary.
- Setting _pFileBoundary property to blank suppresses the file boundary tag in both Load and Save methods.
- Added SoapEnvelopeBoundary and SoapBodyBoundary properties that allow you
to set specific tags when creating a soap packet. They default to
soap:Envelope and soap:Body respectively.
- Added .TagCase property. This defaults to XF:CaseLower. Other options are
XF:CaseUpper and XF:CaseAsIs. In order to have mixed case tags, the Name property for each field in the
group/file/queue must be set.
- Added a section to docs, Creating SOAP Requests.
- Added a section to docs,
Using a View to create a filtered, sorted, XML file.
- Added a new example (Examples\SOAPClient\Convert) courtesy
of Larry Sand (www.ClarionFreeImage.com)
- Added new example (Examples\Dict) that show minimalist source procedures saving
a file, or view, to XML.
- Change: SoapEnvelopeText property (added in version1.52) has changed name to SoapEnvelopeBoundaryAttribute
to make naming more standard.
- Fix: If .Load method opens the file, then it closes the
file as well. If file is closed, and .Save is called, then file is opened,
and closed. If .Save is called in View mode then all necessary files and
view itself, if not already open, will be opened and closed.
- Internal: Calls to .SaveTweakSettings,
and .LoadTweakSettings moved higher in .Save
and .Load methods respectively.
Version 1.52 Beta (7 September 2007)
- Added new Save methods to save a group to a string, and Queue to a
string. .Save(Group) and .Save(Queue) respectively. XML String is in .xmlData
property after the call is made.
- Added .SoapEnvelope property and .SoapEnvelopeText property. If .SoapEnveloper
= 1 then a SOAP envelope will be wrapped around the XML.
Ve
rsion 1.51 Beta (31 August 2007)
- Added support for additional attributes in the file
boundary tag. For example if an XML file is modified in Excel the Schema is
added to the tag that acts as the file boundary:
<file xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
Which is now supported. Additional attributes will be ignored, and
overwritten when the file is saved, however the file will now load as expected.
- Template - added description into extension template header for ease of
identification of which instance of xFiles each extension is.
- Template - fix for legacy class generation (includes xfiles01.tpw 1.54)
Version 1.50 Beta (25 July 2007)
- Documented the xFileLinkDLL class
- New Quick Start guide for dynamic DLL loading using xFileLinkDLL
- Support for loading XML based on field number rather
than field name (allows an XML file to be loaded where the field names don't
match those of the data structure being loaded). Also support starting from
any field in the XML.
- Updated the documentation, fixed incorrect links,
added numerous new links, fixed references where xFilesXML was simply
referred to as "xFiles", update the Contents to assist with navigation and
added additional links to the JumpStart/Quickstart guides in the
documentation.
- New xFileXML.Load()
method to load directly from memory by passing the data structure and string
that contains the XML to load. Using this method means that the
LoadFromString property does not need
to be set and the xFileXML.xmlData does not need to be populated manually.
Version 1.40 Beta (07 July 2007)
- Extensive new document for the xFileXML class, a
large number of new methods and properties have been documented and the
existing documentation expanded on.
- Support for storing multiple data structures in a
single XML file.
- Support for reading data from an XML file that
contains more than the data structure currently being read.
- Support for writing multiple data structures and
custom XML to a single file.
- Added support for Multi-Proj
Version 1.30 Beta (29 June 2007)
- Fixed a bug that could cause problems loading groups
(the data would not be loaded from the XML file, unless Save had previously
been called).
- Updated documentation for the xFileXML class to
include additional class methods, this update is currently a work in
progress and the documentation will be further updated shortly (for all
classes).
- Added xFileXML.SaveBinData()
and xFileXML.LoadBinData() methods to allow
files to be loaded and saved directly to the binData property of the class
without doing any parsing. This can be used to save multiple groups, files
and queues to a single XML file by using the .saveToString property to
create the XML in memory, populating it into the binData property and the
using SaveBinData() to write it to disk. The
standard Load() method handles loading data
from XML files that contains multiple data structures (see below)
- Added support for reading an XML file that contains
multiple groups, files and queues.
Version 1.23 Beta (1 May 2007)
- New example. Uses the xFileTimer object to delay 1ms between tasks.
Version 1.22 Beta (15 February 2007)
- Code to handle nested groups and queues uses the IsGroup() function,
which is not available in version of Clarion prior to C6. In 1.20 Beta this
results in a compiled error when using C55. This code has now been wrapped
in a conditional compile for C6 only.
- Added support for nested groups, queues and records in groups, queues
and records. Previously only groups were handled.
- Fixed compile errors in example applications due to missing Global
extensions.
- The Multi Dimensional example used GPFReporter, Hyperactive and WinEvent,
these have been removed.
Version 1.20 Beta (06 February 2007)
- Updated xFileXML.Copy() function to allow queues to be copied to
files and files to be copied to queue.
- Fixed xFileXML.Copy() function when used with Files -
an option was used that was not supported by some driver types (such as the
IMDD), all functions are now very generic and should support all file drivers.
- Added handling to prevent issues when xFileXML.RemoveDuplicatesAfterSort was
called with a file instead of a queue.
- New handling for tables (especially IMDD tables) to support the same features
as queues.
- Numerous fixes of table handling code, fixed loading and saving issue etc.
- Added the ability to override the main wrapping tag to so that files
and queues can be populated from an XML file regardless of whether the wrapper
tag is <queue> or <file>.
- Fixed: Sub groups and queues (group within groups/queue and queues within queues)
now output correctly. Previously the fields would be output, but the sub
group/queue itself would also be dumped as a single "field" within the XML.
- This is now the official version used by Email Server 3.50 and above. Previous
version of xFiles are not compatible with Email Server source code.
Version 1.10 Beta (3 August 2006)
- Fixed Global Disable (was trying it include some code in the Export from
and Import to file control template which was causing compile errors).
- In Init - don't override settings (with defaults) that were set prior to
Init being called.
- Includes a stamped version to indicate the version of xFiles that the
application was previously compiled with.
- Warning is generated if a XMLFile is attempted to be imported to a file,
or a name for the file is not specified.
- Case insensitive parent method name checking (if the parent method's
name case was different, then the class deriver saw as two different methods).
- Fixed GPF in export to string.
Version 1.09 Beta (19 June 2006)
- Replaces Colons with Dots (for
fieldnames if required) even if the RemovePrefix property is set (was
previously either doing the one of the other).
- Template option to specify whether (in field names) colons must be replaced by dots or not.
- Fixed regression (from 1.08) - omitting fields (where export was not from SendTo)
Version 1.08 Beta (19 June 2006)
- New property - ColumnDisabledStr - a string over the ColumnDisabled byte array (makes setting or resetting
these bytes easy)
- Added a constructor method (which is called from the construct method) - makes deriving the construct
method possible.
Version 1.07 Beta (6 June 2006)
- Very Important !!: self._NoFreeBeforeLoad
has been inversely replaced by self.FreeFileBeforeLoad, self.FreeQueueBeforeLoad
and self.FreeGroupBeforeLoad. You can
turn this on or off in the template (or via handcode).
- Very Important: You need to add the xFiles
Global Extension template to your applications that use xFiles. If you have
used your own derived xFiles class, you will need to enter that into the
field provided on the Class tab of the new xFiles Global Extension template.
- Important: self.InverseOrder
has been replaced by self.InverseAddOrder and self.InverseTruncateOrder
- Important: self._cRecordBoundary
has been replaced by self._pRecordBoundary
- Important: self._cIndent has
been replaced by self._pIndent
- Important: self._cFieldName has
been replaced by self._pFieldName
- Important: self._cRecordBoundary
has been replaced by self._pRecordBoundary
- Important: self.GetValue() and
self.SetValue() prototypes changes - but continue to work as before.
- Important: self._ReplaceColon()
has been replaced by self._ReplaceColonInString().
- Added: Support for Importing and Exporting Clarion Files to and from XML
(so it now handles Files, Queues & Groups). File to xml is only supported
in C55 and above. And files with multi-dimensional fields, memos and/or blobs
are only supported in C60 and above.
- Made import case insensitive for XML tags.
- Added: Dim, Blob & Memo support
- Added: self.SaveEncoding (defaults to iso-8859-1) but can also be set to
utf-8 or windows-1252
- Added: self.LoadEncoding - which tells you what the encoding of the loaded
XML file is.
- Added: CDATA support
- Added: self.SaveStringsToCData (Default off)
- Added: self.SaveMemosAsCData (Default on)
- Added: self.SaveBlobsAsCData (Default on)
- Added: self.SaveAsCData[index] (default off or on depending on
SaveStringsToCData etc. options - override this in SaveTweakSeattings()
- Added: self.DontUseMemos (defaults off)
- Added: self.DontUseBlobs (defaults off)
- Added: CustomHeader (string) - which allows for a custom header string to
be added when creating the header
- Added: CustomSectionAfterFileBoundary (string) - which allows for a custom
section string to be added after the file boundary tag.
- Added: CustomFooter (string) - which allows for a custom footer string to
be added when creating the footer
- Added: Advanced methods - self.SaveTweakSettings() and
self.LoadTweakSettings() - which are called from Load() and Save() after the
analyzing phase before the actual reading/writing phase - allow last minute
changes to the configurations.
- Added: self.ForceDecimalEncode128 which forces all characters > 128 to be
encoding as €
- Added: Control template for Exporting and Importing Files / Queues
and Groups.
- Added: self.RemovePrefix - which if set to 1 will remove the prefix from
queues, groups & files. e.g. <Pro.ProductName> becomes just <ProductName>
- Added: self.FreeGroupData (defaults to a clear)
- Added: self.FreeQueueData (defaults to a free)
- Added: self.FreeGroupData (defaults to a loop / next / delete) - It's
better to override this method with your own ABC Relational Delete - and
xFiles may implement an update feature in future instead of delete and insert
- which can break relational constraints.
- Added: self.RSSVersion (string) which you can set to '2.0' for
example and your file/queue will be exported in RSS format. Best to set this
before calling Save() and/or Load() e.g. Set in Construct()
- Fixed: Critical Section support for C5 and C55 applications that don't use
NetTalk 4.\
- Fixed: interference with other templates (using the Object01.tpw template)
- new xFiles01.tpw
- Fixed: a bug where a 0 byte file could be locked after loading with the
Binary Class
- Added: SaveToString support added (previously was just doing LoadToString)
- Note: the zip functionality (with particular note to the save xml in zip
file functionality) will be undergoing some future changes.
Version 1.05 Beta (27 February 2006)
- Fixed Wait Release problem in Zip code
- Changed Wait Release code to use NetTalk's Wait Release
object if available.
If you are not using the xFiles template, and don't have NetTalk v4.00 or
newer please add the following project define to your application:
xFilesNoNetTalk4=>1
This is not needed if you have NetTalk v4.00 or if you are using the xFiles
Extension Template, as this is controlled automatically.
Version 1.04 Beta (10 November 2005)
- Fixed install. Use this version rather than v1.03.
Version 1.03 Beta (8 November 2005)
- Added column suppression (for SendTo support). See new
property - ColumnDisabled
Version 1.02 Beta (13 September 2005)
- Added zlib_cs.dll and Explode.dll to the Install.
- Tweak to the template for Clarion 5 to remove warnings.
- Removed the p_DontCloseNow parameter to the Save() methods, and added SaveButDontClose() methods
- Fixed Destruct Freeing blocks twice
Version 1.01 Beta (08 September 2005)
- Corrections and additions to the documentation.
- Added an xFiles template to easily add the xFiles object
to a procedure (replaces Object Writer's Object User template, and provides
default settings for xFiles).
- New Save and Load methods that take the data structure
and file name and can be called without needing Init to be called.
- Changed all example to use the new xFiles template to
populate the object.
- Cleaned up and updated the documentation, added docs for
addition class properties.
Version 1.00 Beta (31 August 2005)
- xFiles escapes captivity!
- Initial documentation etc.
- The original class name was changed from QueueFile, all
classes included renamed for consistency.