Agile Documents provides multiple ways to control the selection of content, its assembly and the generation of new documents. As we previously discussed, you may create a template for Agile Document that defines its structure and style; you may drag content from SharePoint Explorer and drop it anywhere within your Agile Document; you may filter the selection of content such as selecting a range of cells in an Excel file; and then you may also save your document to several different output types. However, sometimes you may desire additional functionality and customization. It is because of these cases that we have integrated XSLT into our processes.
Many of the files Agile Document's interacts with--such as Microsoft Word, Excel, PowerPoint, and InDesign--are actually a ZIP file that houses many XML files. So, you can change the extension of a .DOCX file to .ZIP and browse it with WinZip, 7-Zip, or WinRAR or your favorite ZIP editor to see the underlying data. When you leverage the XSLT processes within Agile Documents you can read and update files within this ZIP archive. Really, the sky is the limit in terms of what you can do with XSLT and your files. You could reformat Word tables, you could copy data from several different worksheets in an Excel table and insert it as a completely reformatted Word table and you could also integrate Word or Excel data into an Adboe InDesign document.
You may assign XSLT file(s) to most Agile Document content elements. An XSLT file may trigger the generation of new content and/or may be used to control Agile Document’s importation of content. Said another way, XLST generated output may be saved to any specified SharePoint location or may change what is to be imported into the generated Agile Document. Some potential applications include, creating custom HTML file(s), re-arranging the columns of a table within a Microsoft Word file, selecting data from an Excel Document and transforming it into a stylized Word document as well as automating Adobe InDesign IDML files.
As those who already have a background with XSLT might be wondering, how do you perform XSLT operations on a Microsoft Office and Adobe InDesign files? The more traditional approach is to pair an XML with an XSLT and then perform the the transformation. As we alluded to above, since 2007 the Microsoft Office file formats (.DOCX, .XLSX, .PPTX, etc) are actually a ZIP archive. Inside the ZIP archive are several folders and XML files. The same ZIP archive structure is also true for InDesign IDML files. Agile Documents leverages a custom XSLT processing instruction bc-agiledocuments that points to the input source and the output destination of the XSLT process.
You might also be wondering if there are Agile Documents schema specific XML structures that need to be implemented. The short answer is no, this system is designed to create the schema specific XML structure for the particular output file you are creating. Thus, the XSLT that is applied to a Microsoft Office document must adhere to the schema defined by Microsoft for Office Open XML. The same is true for Adobe InDesign IDML or any other ZIP archive structure you wish to leverage.
As shown in Figure 1, to associate an XSLT with a particular content element, drag and drop the desired XSLT from the SharePoint Explorer pane to the Drag files from SharePoint Explorer and drop them here shaded rectangle in the Code pane. Make sure you first select the appropriate content item -- in this case we are associating it with Word1_UnstyledTables.docx. Once you have dragged some XSLT(s) into the shaded rectangle, you will see them appear in the list box below -- also shown in Figure 1. You may select an item in the list to control its order of processing (move it up or down) as well as it remove it from processing. You may also configure the XSLT(s) parameters, as appropriate. In the case of Figure 1, you may configure the XSLT's Destination, ZIP Destination, ZIP Source, and ZIP Template.
It should be noted that using an XSLT file is a programmatic solution. There are countless XSLT resources on the web that do an excellent job explaining how to use XSLT. Here is one. The purpose of our discussion here is not explain XSLT, but rather the customization needed to leverage the technology within Agile Documents.
There are three key XSLT integration points for Agile Documents:
The bc-agiledocuments Processing Instruction provides Agile Documents specific information as to how the XSLT should be applied. It should be the first line, or near the top, of your XSLT file. An example Agile Document XSLT processing instruction is shown below.
<?bc-agiledocuments zipsource="xl/worksheets/Sheet1.xml" ziptemplate="Template/Template.docx" zipdestination="word/document.xml" destination="MyNewWordFile.docx" ?>
The bc-agiledocuments processing instruction has four attributes: zipsource, ziptemplate, zipdestination, and destination. They are described below.
|zipsource||This attribute specifies the relative file path of an XML file you wish to apply the XSLT to inside the zip archive (i.e. an XML file within an Office Open XML zip file). This XML document is combined with the specified XSLT to produce an output.|
|ziptemplate||This optional attribute allows for the specification of a template instead of the source document. Its location is relative to the [parent] Agile Document’s location on Sharepoint. An example would be when you want to collect data from an Excel file but render it within a Word file. In that case, you would need to specify a template Word file. If you did you specify a Word template, the assumption is that the XSLT output would be stored in said Word template. Therefore, you should specify where to store the XSLT output through the zipdestination attribute.|
|zipdestination||This represents the relative path within the ZIP file you wish to store the output. If you specified a ziptemplate, it would be the relative path within the template. If you did not specify a ziptemplate, it will be stored in the original zip archive.|
This specifies the output location of the results. If nothing is specified, then the output ZIP--with the updated XSLT output--is fed into the generated Agile Document. For instance, you might have applied an XSLT to style the tables in a Word file and the updated Word file was inserted into the Agile Document you were creating. If it is specified, the output is copied to the specified path relative to the Agile Document's output folder. In this later case, it might be helpful to pair with the Exclude Insertion option (Figure 2).
An example would be transforming an Excel file to a Word file, where you only want the Word file inserted. Thus, you would apply the XSLT processing to the Excel file and also specify a zipsource, ziptemplate, zipdestination and set Exclude Insertion to true. Next you would specify a destination attribute to overwrite a Word file that was to be included in your Agile Document. Please note, that this Word file should be placed in the Agile Document after the Excel file. Otherwise you will insert the results of the Word that resulted from the previous XSLT processing of the Excel file.
XSLT allows for the specification of local or global parameters [or variables]. An example parameter definition is shown in Figure 3. Agile Documents can override these values by "configure"-ing the XSLT. In this way, a generic XSLT can be applied in a multitude of ways without the need to create a separate XSLT for each variation. One such example, is styling tables within word. You may not have realized, but there are predefined tables styles in Word. We can leverage a single XSLT to style all our tables according to a named style we configure for the XSLT.
When configuring an XSLT, Agile Documents loads the XSLT and searches for global parameters. Any global parameters can be overridden through Agile Documents. Further, Agile Documents provides context sensitive help by reading any XML comment than may appear with the xsl:param node. The help text appears when you click on the ? icon to the right of the parameter. Please note the xml comment at the top of the screen shot (Figure 4) matches the description in the code block (Figure 3). The paramTableStyle parameter can be seen in the lower right hand side of Figure 3.
Please note that if no value is specified in Agile Documents, the default value is used. In the case below, GridTable4-Accent5 will be used.
<xsl:param name="paramTableStyle" select="'GridTable4-Accent5'" /> <!-- The table style. Chose a table style defined in Word minus any spaces. Examples include: 'GridTable1Light', 'GridTable1Light-Accent1', and 'GridTable5Dark-Accent2'. Remember, no accent is a dark gray, Accent1 is light blue, Accent2 is red orange, Accent 3 is light gray, Accent 4 is yellow-orange, Accent 5 is dark blue, Accent 6 is green. --> </xs:param>
ZIP archives, such as Microsoft Excel XLSX files, are actually a collection of files that are related in some way. In the case of XLSX files, there is a worksheet file within the ZIP (ex. xl/worksheets/Sheet1.xml) and there is also a string table with the ZIP (ex. xl/sharedStrings.xml). If you type text in an Excel spreadsheet, the text is stored in sharedStrings.xml which is linked from Sheet1.xml. Thus, your Excel spreadsheet contains spreadsheet data in both Sheet1.xml and sharedStrings.xml. As you apply an XSLT to Sheet1.xml it might become necessary to also reference sharedStrings.xml at the same time. In these cases, you must leverage the XSLT function base-uri() to reference the location of another file. The base-uri() is specified at the root of the zip archive. Since, XSLT processing is done in a temporary folder, base-uri() translates to something like X:\temp\SomeRandomFolderNamePertinentToTheXSLTTask\ZIPFileName. An example use of base-uri() in an XSLT file is shown below.
<xsl:param name="sharedstrings" select="'xl/sharedStrings.xml'" /> <xsl:variable name="sharedstrings_doc" select="doc(resolve-uri($sharedstrings, base-uri()))" />
On line 1, we define an XSLT parameter that points to the location of SharedStrings.xml within the ZIP archive. On line 2, we concatenate base-uri() with the SharedStrings.xml file path to create a reference to said file. Behind the scenese, the file's location is computed as X:\temp\SomeRandomFolderNamePertinentToTheXSLTTask\ZIPFileName\xl\sharedStrings.xml.