xFiles Documentation
  xFiles header
Vote for this Product at ClarionShop
 
Buy now at ClarionShop
Version
CapeSoft Software copyright
www.capesoft.com
Updated 24 January 2012
c3pa approved
     

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:

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

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

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

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. Global Template Options

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: Extension screenshot 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.
 Control Buttons screenshot You can setup the following options in the control template: Control Template General Control Template Options tab screenshot

Some Practical Applications

Creating RSS Feed Files

  1. 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.
  2. Your RSSFeedQueue should be of the following example structure:
  3. 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).
  4. 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>'

    ! This will load the existing RSS feed into our RSS feed queue
    ThisXMLFile.RSSVersion = '2.0' ThisXMLFile.load(RSSFeedQueue,'RSSFeedfile.xml')
  5. 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'):
  6. Item.Title = 'My New Item'
    Item.Description ='My new RSS feed description'
    Item.Link = 'www.mywebsite.com\MyNewItem.htm'
    Add(Item,1)
  7. 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) ! This group will be stored in the XML settings file
WebSite               string(252)
EmailAddress          string(252)
                    end
FTPPostWindowThread  long              
! Not stored in the XML settings file

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;
  1. Get the class ready, by setting the Root-Node (the wrapper around the whole thing) and telling the class not to automatically close the root node.
    xml.RootBoundary = 'whatever'
    xml.DontCloseTags = 1
  2. Save the first entity as normal
    xml.Save(ReportFormat ,Loc:XmlName,'Document','Record')   !(For saving to a file)
    xml.Save(ReportFormat ,'Document','Record')  
    !(For saving to a string)
  3. Set the append flag so the following items are appended
    xml.append = 1
  4. Add as many entities to the file as you like, using the normal techniques. Although the boundaries do not have to be unique you may chose to make them unique so they can be loaded separately later on.
    xml.Save(rrDefnFieldsLocalView,Loc:XmlName,'DefnFieldsLocal','Record')
    xml.Save(rrDefnFieldsGlobalView,Loc:XmlName,'DefnFieldsGlobal','Record')

  5. 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')
! this is the output tag name, not the field name
  ! 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.
ClassDescription
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

horizontal rule

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()


up icon

horizontal rule

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()


up icon

horizontal rule

xFileXML.Init (*Queue p_Queue, string p_FileName)

xFileXML.Init (*Group p_Group, string p_FileName)

xFileXML.Init (*File p_File, string p_FileName)

xFileXML.Init (*View p_View, string p_FileName)

Initialises the xFileXML object to the a particular data structure and file, you can call this method at any point to change the data structure that is read from and written to, and the XML file that is used. If you are setting any of the class properties such as LoadFields and SaveFields then Init must be call after setting the class properties in order to use them.

Note: As well as passing a Queue, you can also pass a Group, File or View to the Init method to have xFiles read and write using a group, file, view or queue. (Views are Write-Only, not Read).

Note: You don't need to call Init unless you set advanced class properties like xFileXML.loadFields, xFileXML.saveFields and xFileXML.copyFields. If you set these properties to change which fields are saved then you need to use the first method above and call Init(). Otherwise you can call the Load and Save methods and pass them the queue/group/file/view and file name without calling Init().

Parameters:

  Parameter   Description
*Queue p_Queue or *Group p_Group The label of the queue or group that the data is read from and written to.
string p_FileName The name of file to read from and write to.

Examples

  Example  
! DATA
myQueue           queue
from                  string(80)
to                    string(80)
end

xmlFileName       string(260)

! CODE
    xmlFileName = 'myXmlFile.xml'
    thisFileXML.Init(myQueue, xmlFileName)


See Also:

xFileXML.Load(), xFileXML.Save()


up icon

horizontal rule

xFileXML.Load (*Queue p_Queue, string p_fileName, <string p_FileBoundary>,<string p_RecordBoundary>)

xFileXML.Load (*Group p_Group, string p_fileName, <string p_FileBoundary>,<string p_RecordBoundary>)

xFileXML.Load (*File p_File, string p_fileName, <string p_FileBoundary>,<string p_RecordBoundary>)

xFileXML.Load (*Queue p_Group, *String p_XMLString, Long p_XMLStringLength, <string p_FileBoundary>,<string p_RecordBoundary>)

xFileXML.Load (*Group p_Group, *String p_XMLString, Long p_XMLStringLength, <string p_FileBoundary>,<string p_RecordBoundary>)

xFileXML.Load (*File p_File, *String p_XMLString, Long p_XMLStringLength, <string p_FileBoundary>,<string p_RecordBoundary>)

xFileXML.Load ()

Loads an XML file into the data structure.

The first parameter is the Clarion data structure that will receive the parsed XML. Valid structures are a Queue, File or Group.

The second parameter is the name of the file on disk, or the name of the string which is holding the XML in memory. If the XML is in a string, then an additional parameter, the length of the string, is required at this point.

Following this are 2 optional parameters that allow you to specify the File Boundary, and Record Boundary tags.

The .Load method (no parameters) ultimately loads the XML into the specified structure. It is included here for completeness but it should not usually be called directly.

Parameters

  Parameter   Description
*Queue p_Queue or
*Group p_Group or
*File p_File
The queue, file or group that the xml data will be loaded into.
string p_FileName The name of file to read from.
*String p_XMLString The string variable containing the whole, valid, XML data.
Long p_XMLStringLength The length of the XML string.
<string p_FileBoundary> The file boundary tag in the XML file.  Optional. Default is file, view, queue or group. If the p_FileBoundary parameter is set then the p_RecordBoundary parameter must be set as well.
<string p_RecordBoundary> The Record boundary tag in the XML file. Optional. Default is item (for File or Queue) or data (for Group). If the p_RecordBoundary parameter is set then the p_FileBoundary parameter must be set as well.

Examples

  Example 1 - Calling Load by passing the data structure and file name.
 ! DATA
myQueue           queue
from                  string(80)
to                    string(80)
                  end

xmlFileName       string(260)

  CODE
    xmlFileName = 'myXmlFile.xml'
    thisFileXML.Load(myQueue, xmlFileName)


  Example 2 - Calling Load after calling Init
 ! DATA
myGroup           group
from                  string(80)
to                    string(80)
                  end

xmlFileName       string(260)

  CODE
    xmlFileName = 'myXmlFile.xml'
    thisFileXML.Init(myGroup, xmlFileName)

    thisFileXML.Load()

See Also:

xFileXML.Save(), xFileXML.Init(), Loading XML Files

up icon
horizontal rule


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
 ! DATA
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()


up icon

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
  ! Add data to the string, such as custom XML 
  xFileXml.binData = Clip(string1) & Clip(string2)
  xFileXml.SaveBinData('myfileName.xml')
 

See Also

LoadBinData(), Save(), Load(), binData, binDataLen, saveToString, loadFromString

up icon
horizontal rule

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
up icon
horizontal rule

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()

up icon
horizontal rule

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()

up icon
horizontal rule

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()

up icon
horizontal rule

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()

up icon
horizontal rule

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

 

up icon
horizontal rule

 

Record handling and management

up icon
horizontal rule

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()

up icon
horizontal rule

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()

up icon
horizontal rule

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()

up icon
horizontal rule

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()

up icon
horizontal rule

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

 

up icon
horizontal rule

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

 

up icon
horizontal rule

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

 

up icon
horizontal rule

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

up icon
horizontal rule

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()

 

horizontal rule


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()

 

up icon
horizontal rule

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.

 

up icon
horizontal rule

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

 

SOAPEnvelope long

When this property is set the Save() method wraps a SOAP envelope around the XML data.

See Also

Creating SOAP requests
SOAPEnvelopeBoundary, SOAPEnvelopeBoundaryAttribute, SOAPBodyBoundary

 

SOAPEnvelopeBoundary pString(252)

This property determines the text for the Soap Envelope tag, to be used if the XML is wrapped as a SOAP request. The default is <soap:Envelope>. Be aware that some SOAP servers may treat this tag in a case sensitive manner.

See Also

Creating SOAP requests
SOAPEnvelope, SOAPEnvelopeBoundaryAttribute, SOAPBodyBoundary

 

SOAPEnvelopeBoundaryAttribute pString(252)

This property lets you set the attribute (if any is required) of the Soap Envelope Boundary tag.

See Also

Creating SOAP requests
SOAPEnvelope, SOAPEnvelopeBoundary, SOAPBodyBoundary

 

SOAPBodyBoundary pString(252)

This property determines the text for the Soap Body tag, to be used if the XML is wrapped as a SOAP request. The default is <soap:Body>. Be aware that some SOAP servers may treat this tag in a case sensitive manner.

See Also

Creating SOAP requests
SOAPEnvelope, SOAPEnvelopeBoundary, SOAPEnvelopeBoundaryAttribute

 

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

xFileLinkDLLProperty Reference

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
  1. I declare the object and call Load/Save but nothing happens.

    xFiles provides two ways to handle loading and saving of XML files:
    1. 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)

    2. 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.
  2. 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

Clarion 5.5 Support Limitations

The following features are not available in the Clarion 5.5 version of xFiles

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 sales at capesoft dot com
Telephone +27 21 715 4000
Fax +27 21 715 2535
Post PO Box 511, Plumstead, 7801, Cape Town, South Africa

Buy Online
Web Buy now at ClarionShop www.clarionshop.com

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)

Version 2.27 (11 October 2011)

Version 2.26 (6 Sept 2011) 

Version 2.25 (20 July 2011)

Version 2.24 (28 June 2011)

Version 2.23 (4 May 2011)

Version 2.22 (24 March 2011)

Version 2.21 (24 March 2011)

Version 2.20

Version 2.19

Version 2.18

Version 2.17 (24 January 2011)

Version 2.16 (19 January 2011)

Version 2.15 (14 January 2011)

Version 2.14 (1 December 2010)

Version 2.13 (27 November 2010)

Version 2.12 (15 November 2010)

Version 2.11 (26 September 2010)

Version 2.10 (24 August 2010)

Version 2.09 (4 August 2010)

Version 2.08 (23 July 2010)

Version 2.07 (12 July 2010)

Version 2.06 (18 May 2010)

Version 2.05 (2 April 2010)

Version 2.04 (March 2010)

Version 2.03 (1 March 2010)

Version 2.02 (17 February 2010)


Version 2.00 (5 January 2010)

Version 1.99 (11 December 2009)

Version 1.98

Version 1.97

Version 1.96

Version 1.95

Version 1.94 (20 August 2009)

Version 1.93 (13 August 2009)

Version 1.92 (28 July 2009)

Version 1.91 (21 July 2009)

Version 1.90 (15 July 2009)

Version 1.89 (13 July 2009)

Version 1.88 (18 May 2009)

Version 1.87 (6 May 2009)

Version 1.86 (17 April 2009)

Version 1.85 (4 April 2009)


Version 1.84 (23 March 2009)

Version 1.83 (12 March 2009) Version 1.82 (10 March 2009) Version 1.81 (26 February 2009) Version 1.80 (19 February 2009) Version 1.78 Beta (10 November 2008) Version 1.77 Beta (23 September 2008) Version 1.76 Beta (12 September 2008) Version 1.75 Beta (10 July 2008)  Version 1.74 Beta (19 June 2008) Version 1.73 Beta (16 June 2008) Version 1.72 Beta (12 June 2008) Version 1.71 Beta (11 June 2008) Version 1.70 Beta (19 May 2008) Version 1.69 Beta (13 May 2008) Version 1.68 Beta (2 April 2008) Version 1.67 Beta (14 March 2008) Version 1.66 Beta ( 14 March 2008) Version 1.65 Beta (29 Feb 2008) Version 1.64 Beta (20 Feb 2008) Version 1.63 Beta (15 Feb 2008) Version 1.62 Beta (5 November 2007) Version 1.61 Beta (26 October 2007) Version 1.60  Beta (13 September 2007)  Version 1.52  Beta (7 September 2007) Version 1.51  Beta (31 August 2007) Version 1.50  Beta (25 July 2007)

 

Version 1.40  Beta (07 July 2007)

 

Version 1.30  Beta (29 June 2007)

 

Version 1.23  Beta (1 May 2007)

 

Version 1.22  Beta (15 February 2007)

 

Version 1.20  Beta (06 February 2007)

Version 1.10  Beta (3 August 2006)

Version 1.09  Beta (19 June 2006)

Version 1.08  Beta (19 June 2006)

Version 1.07  Beta (6 June 2006)

 

Version 1.05  Beta (27 February 2006)

Version 1.04 Beta (10 November 2005)

Version 1.03 Beta (8 November 2005)

Version 1.02 Beta (13 September 2005)

Version 1.01 Beta (08 September 2005)

Version 1.00 Beta (31 August 2005)