Find help fast by searching “xpressdox [command name]” in Google

Saving Assembled Documents into iManage


All that is needed for this feature to be enabled is that a drive letter be configured to refer to the iManage system.  This configuration operation can be accomplished by a user with a Supervisor license, which will give the user access to the Foreign File Systems tab in the XpressDox configuration screen.


Choose the Foreign File Systems tab, click the Add New button on the left, and then enter the name and drive letter that you would like to use. The name is purely a description, and any drive letter that you know is unused can be chosen.  You will see that two file systems are currently supported, i.e. Windows and iManage – but Windows is disabled as this is the default and it is not necessary to define the Windows file system for any drive letters.  But you do need to choose the iManage radio button.

It is then necessary to click the Use File System’s Editor button which will present you with a form to complete.


Notice that the various fields can contain the <> syntax – in the above example the values of the iManageUserName and iManagePassword data elements which are active at the time access to the iManage system is done will be filled in.

After saving the configuration, you can then press the Test button to make sure the information has been configured correctly.

Addressing the iManage System

Once this configuration has been done, saving assembled documents into iManage is done just by specifying the path to the folder or sub-folder and using normal syntax for a file path for the Windows file system. For example

The file name will be provided either by a command in the template, or will default to the template file name with a .docx extension.

There are many “profile properties” that can be set for a document in the iManage system.  XpressDox will default some of them, but all of the defaults, plus the custom properties, can be set inside the template using the SetCustomDocumentProperty command, as in the following examples, that set the custom1 and custom3 properties for the document:



Note that XpressDox will regard custom document properties with the name starting with XDfsProf- as being applied to document management systems, and the part of the name following that prefix is the name of the DMS profile property.


The GetDataset Function

This function was introduced to enable the entire dataset to be saved as a BLOB in a data base.

Typically, this function will be used in the context of a SetDataSourceData function, something like this:

«SetDataSourceData(‘StagingDataSource’,Guid(), 'XMLBlob',GetDataset(), 'Description',Name)»

In the above, the value of the Guid() function would be used as an arbitrary, unique, ID of a staging table, XMLBlob is the name of the BLOB column into which the data set (from GetDataset()) is written, and the Description and Name are the name and value (respectively) to be written into another column in that row in the table.

The ApplyRulesToDataset Command

It may be that all, or at least some, of the data set to be used to assemble a document comes from some place other than the interview.  For example, it might be that the data are in a data base, or retrieved from a web service or some other data source.  Often data sets like this can contain data elements which are wrongly formatted or which in some other way do not conform to the business rules for the template that is being run.  In this case it might cause a dangerously inaccurate document to be assembled from the data and template.

The ApplyRulesToDataset command will cause all the Rule commands to be executed against the data set, regardless of whether there is an interview or not.

The Rules will be evaluated just before the data set is passed to the assembly engine where the data set is merged into the template. If any of the rules fail, then an error message will be displayed and the assembly terminated.

The ApplyRulesToDataset takes one argument, with the following meanings:

  1. «ApplyRulesToDataset(Yes)»: the command will be applied.
  2. «ApplyRulesToDataset(IgnoreSoftRules)»: any “soft” rules (see Tips and Hints using the Rule Command) will be ignored.
  3. «ApplyRulesToDataset(No)»: the command is ignored completely.


The AppendPDF Command

AppendPDF enables the user, and also the template author, to choose one or more PDF files which will be appended to the document assembled by the template in which the command appears.  The SaveAsPDF(Yes) command is issued implicitly.  In other words, PDF files can only be appended to other PDF files.

Example – user supplies the file name


will present the user, in the interview, with a place to enter the name of the PDF file to be appended.

Example – template author supplies the file names

«AppendPdf(‘.\ClauseFiles\Pdf File.pdf|.\ClauseFiles\Test Proposal.pdf’)»

will cause the two files Pdf File.pdf and Test Proposal.pdf to be appended to the assembled document. Note that the “pipe” symbol is used to separate files in the list of files to be appended.

The Data Set Data Source

When you have a system of templates and have run them a number of times, say for a number of your customers, the saved data set files become a source of valuable information.  It would be nice to be able to access those data files as though they were a database.

That’s what the XpressDox Data Set Data Source will do for you.

You configure the data set data source in much the same way as any other data source – via the XpressDox configuration.

Choose the New Data Source button and you will be presented with a list of choices.  Towards the end, on the right, is the radio button with the caption “XpressDox Data Set Data Source”.

Choose that and press “Finish”.

After that, you will need to give the data source a name, press Tab and then press the Use Data Source’s Editor button to edit the Definition String.

Once you’ve pressed that button, then the really exciting work starts. You will see a form like this:

Pressing the little “?” on the top right of the form will give you some help on the different options.

In the end, a picture is worth a thousand words, and the best way to find out what this data source does is to try out various options and test the result (with the “test data source” button, or just double-click the data source name) and see what XML structure is created. Thereafter you will probably know quite well how to address the data inside a template.

The SetDataSourceData Function

Values in databases can be changed by the user in the interview using the various “Save” options as described in Control how the user can change data source data.

The template author can also instruct XpressDox to modify values in a data base, using the SetDataSourceData function.

As an example, suppose there is a data source defined in the configuration called Customer which addresses a CustomerDetails table in a database. The following fillpoint would cause the values in the database to be changed:

«SetDataSourceData('Customer',CustomerID,'Fullnames',concat(FirstNames, ' ', LastName),'PreferredLanguage',IIf((Lang = ''),'English',Lang))»

This fillpoint will cause the following actions:

  1. The row in the CustomerDetails table with a key whose value is in the CustomerID data element will be retrieved, and the values of the Fullnames and PreferredLanguage columns in that row will be modified as below.
  2. The value of the Fullnames column will be built up from the values of the FirstNames and LastName data elements, with a space between them.
  3. The value of the PreferredLanguage column will be set to the value of the Lang data element, if it has a value, otherwise the PreferredLanguage column will be set to ‘English’.

Up to 10 pairs of ColumnName,Value pairs can be specified in one call to SetDataSourceData.

Download the AdventureWorks database

Some of the sample templates which are delivered with XpressDox make use of one of the early instances of the Microsoft AdventureWorks SQL Server database.  This database can no longer be obtained from any Microsoft web site, and so a backup is made available here.

You can download either the .bak file itself, by clicking on the following

.bak: Download AdventureWorks.bak file

or, if preferred,

.zip: Download file

Once this has been downloaded, you can use the Microsoft SQL Server Management Studio, or any other suitable application, to install the database on a test system.

Using a Stored Procedure as a Data Source

This Cookbook article refers to the AdventureWorks database which needs to be installed at a location available to your development environment. If you have not already done so, you can download the database from Download the AdventureWorks Database.

It is assumed that you already know how to configure a datasource for a SQL Server database.  If not, it is strongly recommended that you do so.  You can follow the process by looking at the Cookbook articles Use a SQL Server Data Source to include Customer information on a template and/or Configure A Data Source for an Elite Database.

The process of defining a stored procedure as a data source is almost the same as that for defining a normal table or view as a data source, with the following differences:

  • Where the configuration wizard presents a choice of tables and views, it will now also include the stored procedures in that list.
  • Once a stored procedure is chosen, then configuration wizard will end, and give you the opportunity to modify the Definition String, using the Use Data Source’s  Editor button for that.

Some concepts to bear in mind are (these concepts are all illustrated in the sample template Using a Stored Procedure as a Data Source.xdtpx which is delivered into the My Documents\XpressDox\Samples folder by the XpressDox desktop installer):

  1. All data sources require that an “ID” be defined, by which unique items can be retrieved from a data source.  For a table or view, the ID is typically the primary key, or some other unique identifier such as an account number, or person number.  In the case of a stored procedure, the ID consists at least of the arguments to the stored procedure, but may have more components.  For example, in the case of the AdventureWorks database, the stored procedure dbo.uspGetManagerEmployees will get all the employees for a given manager.  In this case the ManagerID is the single argument which needs to be sent to the stored procedure, but since this stored procedure returns a collection of Employee objects, an extra item, viz. the EmployeeID, is necessary as part of the ID of this data source.  This is to make sure that the system knows how to distinguish between the multiple Employee objects returned by this stored procedure, which will have the same ManagerID.
  2. The usual data source retrieval commands can be used to get the data returned by a stored procedure.  The above-mentioned sample template uses the LinkToDataSource Command and this is arguably the command which suits stored procedures best.
  3. As template author, you should have knowledge of what kind of information a stored procedure returns.  If it returns a scalar value, or a number of scalar values (such as the Sales.uspGetEmployeeSalesYTD stored procedure used in the above sample), then the LinkToDataSource (or other data source command) should specify the “id=<EmployeeID>” type syntax.  If, however, the stored procedure returns a collection, then the “range=…” syntax should be used.  For example, if dbo.uspGetManagerEmployees is called using something like “id=<ManagerID>” in the data source command, then only the first Employee for that ManagerID will be returned.  Calling the dbo.uspGetManagerEmployees stored procedure should be initiated using the “range=<ManagerID>” syntax in the data source command.

The GetDataSourceData, GetXMLElementValue and GetXPathValue functions

If you need to get data from a data source and have those data available in an interview (and hence in the data set), then the commands IncludeDataSourceData and ChooseFromDataSource would be what you would use.

If, while authoring the template, you come to a point where you need one or more the values of fields in a data source, and the ID of the data source is known to you, then you can use the GetDataSourceData() function to retrieve the field(s) in question.

In order to discuss these functions, imagine a scenario where you know the identity of the user who is running the template – you would use the WindowsLogonUser() function to find this. Imagine also that you have set up a data source with all of the users’ details in it (called “USERS”), where the ID of the data source is that username.

Getting the value of one field

At some point in the template you want to put the user’s first name (e.g. after “Dear”). This would be achieved like this:


This will get the row from the USERS data source where the ID is the WindowsLogonUser, and retrieve the ‘FirstName’ column from that row and put its value into the document.

Getting more than one field value

Imagine now that you would like to, say, end off a letter template with all of the user’s contact information, like full name, email address, direct phone line, etc. You could issue a GetDataSourceData for each of these fields, but each call to the function will cause a new access to the database, which can be inefficient of resource usage and time.

There is another form of the GetDataSourceData() function which omits the field name, and when this call is executed it returns, not a field/column value, but an XML representation of the data source row. Then the new function GetXMLElementValue will be used to retrieve individual field values from that XML. An example of that would be:


«GetXMLElementValue(Getv(‘xml’),'FirstNames')» «GetXMLElementValue(Getv(‘xml’),'Surname')»
Email Address: «GetXMLElementValue(Getv(‘xml’),‘EmailAddress’
Direct Line: «GetXMLElementValue(Getv(‘xml’),‘DirectLine’)»

Complex Operations

If you are familiar with XPATH, then you can use XPATH functions to extract information from the XML string that has been retrieved. For example, in order to get the count of the number of Product elements in a retrieved XML string, this would be the code to use:

The number of products are: «GetXPathValue(Getv(‘xml’),‘count(//Product)’).

You could even get the sum of the cost price for all the Product elements like this:

The total cost price of all products is: «FormatNumber(GetXPathValue(Getv(‘xml’),‘sum(//Product/CostPrice)’)).