Transforming XML

By itself, the capability to turn FileMaker data into XML is not terribly useful. The reason is that FileMaker emits the XML in one of its specialized grammars. Even though other applications can read the file containing the exported data, they might not be able to make much sense of the FMPDSORESULT and FMPXMLRESULT grammars. In fact, this is a general issue with XML-aware applications: They all work with different formats and structures of XML.

Lets say there exists a tool (call it WidgetPro) that can read information about widgets from an XML file, as long as the XML file looks like whats shown in Listing 22.4.

Listing 22.4. The WidgetPro XML Format

789 Large Flanger blue 45 790 Granite Auger Slate 715

We can get widget data from FileMaker, and we can get it as XML, but the two XML documents have different structuresthe same data, but expressed with different tag names and tag structures.

This is an important point to understand about XML: XML is not in itself a language or a file format. Using XML, the same data can be described ("marked up," as its often said) in many different ways. For applications to share data via XML, its not enough for each application to support reading and writing data in its own, specific XML format. There has to be some means to translate between different forms of XML as well. In the widgets example, this means that we need to take the "FileMaker widget XML" and make it look like "WidgetPro widget XML." This leads to the concept of XML transformations.

Figure 22.4 illustrates the idea of an XML transformation. From the FileMaker Pro database of widget information, we first need to export the widget data in an FMPXML structure. Next, we need to transform that XML so that it looks like WidgetPros XML structure instead. Finally, we bring the transformed XML into WidgetPro. Figure 22.4 sketches what this process would look like.

Figure 22.4. An XML transformation pipeline. FMPXMLRESULT (emitted by FileMaker) is transformed into WidgetPro XML (accepted by WidgetPro).

Introducing XSL Stylesheets

It turns out that XML already has a transformation technology available for us. That technology is called XSL, which stands for eXtensible Stylesheet Language. The stylesheet turns out to be the transformer. In much the same way that a word processing or page layout stylesheet can take ordinary text and transform it into formatted text, an XSL stylesheet can take one form of XML and transform it into another (or into any other text-based format, actually), as shown in Figure 22.5.

Figure 22.5. An XML transformation pipeline that uses an XSL stylesheet to accomplish the transformation.

Note

You might often see the terms XSL and XSLT (which stands for XSL Transformations) used interchangeably. Technically they e distinct; XSLT is in fact a subset of XSL. But when people speak of XSL they e generally referring to XSL transformations, so we won make a major point of distinguishing between the two terms.

So what is an XSL stylesheet? Its a series of commands that describe how to transform XML input into some new form. The new form can also be XML (and often is), but its possible to use a stylesheet to transform your XML into other text-based formats as well: tab-separated text, HTML, or more complex formats such as PDF and RTF. Interestingly, the XSL transformation language is itself a variety of XML, so XSL stylesheets are also valid XML documents in their own right.

Heres an example of an XSL stylesheet that would transform the "FileMaker widget XML" into "WidgetPro XML" (see Listing 22.5).

Listing 22.5. An XSL Stylesheet

[View full width]

:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="fmp">

Our goal, remember, is to take the original XML output from FileMaker (Listing 22.3) and translate that output into a new form of XML that contains much the same information, but in a different structure (Listing 22.4).

The stylesheet in Listing 22.5 contains two kinds of statements: On the one hand there are XSL commands (which you can tell by their xsl: prefix), and on the other hand are the actual XML tags that the stylesheet will output. The stylesheets job is to pick through the original XML document and decide which pieces of it to output, and in what order.

Analyzing a Stylesheet

If youve never read through an XSL stylesheet before, this section may be useful. Well go through the stylesheet in Listing 22.5 line by line to illustrate its inner workings.

The XML Declaration

Every XML document begins with an XML declarationand XSL stylesheets are XML documents. Simple enough.

The Stylesheet Statement

[View full width]

xsl="http://www.w3.org/1999/XSL/Transform">

The xsl:stylesheet statement announces the document as an XSL stylesheet. The stylesheet statement also declares two XML namespaces (thats what the xmlns stands for). Namespaces are an important XML concept, but like most of the finer points of XML, namespaces are a bit too complex a topic for us to spend much time on in this book. Suffice it to say that both the namespaces declared here are necessary. The second namespace, which is abbreviated xsl, is common to all XSL stylesheets, and is used to distinguish all the XSL stylesheet commands from other forms of XML. (These commands, again, begin with the same xsl: prefix thats specified by the namespace.) And the fmp namespace declaration is crucial as well because it matches the namespace declaration that appears at the start of any XML document output by FileMaker. Well have a bit more to say about the FileMaker namespace farther on.

Note

Notice also that the stylesheet declaration includes a statement called exclude-result-namespaces. This rather important command prevents namespaces declared in the source document from being carried through to the output document. In general, we recommend you use this command in the element of your stylesheets to strip all FileMaker-specific namespaces from your output. The exclude-result-namespaces attribute uses a space-delimited list of namespace prefixes to decide what to strip out. In Listing 22.5 just one namespace is being stripped, so it says exclude-result-prefixes="fmp". If there were multiple namespaces to strip (as there often are in FileMakers Custom Web Publishing), you would say something like exclude-result-prefixes="fmp fml fmr fmrs". This would exclude all four namespaces from the stylesheets output.

FileMakers Custom Web Publishing is covered in depth in Chapter 23, "Custom Web Publishing," p. 699.

Specifying the Output Type

The xsl:output statement tells the XSL processor what type of document is being output. If you e trying to produce XML output, you need to include a statement like this one so that the XSL processor adds the appropriate XML declaration to the final document. The output statement also includes an attribute called indent when this is set to yes, the XSL processor tries to format the XML output in a pleasing and readable way.

Using a Template to Find the Result Set

[... code omitted ...]

The concept of a template is crucial to XSL. Templates are a way for the stylesheet writer to specify which parts of the source document shes interested in. In this case, we e telling the processor we want to find the element called in the source document and do something with it. Youll notice that this template takes up all the rest of the stylesheetso the rest of the stylesheet tells what to do with the after weve found it.

Just inside the xsl:template statement is some actual XML, in the form of a tag. This tag is matched by the tag at the very end of the template instruction (almost at the end of the document). These two tags, unlike the xsl: commands, aren instructions at allthey represent XML that will be output. So the xsl:template here is saying "When you find a tag, output a ... tag pair, and then go on to do some other things inside it."

Of course, inside the tag we want the stylesheet to emit XML that describes the individual widget records, which is what the next part of the stylesheet does.

Using xsl:for-each to Loop Over a Result Set

The tag is a looping construct. Right now, we e inside the XSL template that matches an tag, so the command tells the XSL processor to find all elements that are children of elements inside the . The additional commands inside the ... tag pair furnishes instructions on what to do with each element that we find.

For each in the original FileMaker XML, we want to output a element, and thats what the next line does. Additionally, the element needs to have an attribute called index, which shows the numerical position of the widget, in sequence. The position() function thats used in that line gives the position of the current element. (We wrap the function call in curly braces so that the XSL process knows its a command, and not literal text to be output with the XML.)

Using xsl:choose to Determine Output

[other columns omitted for brevity]

At this point, we e inside the element in the original FileMaker XML, and from an output standpoint, we e inside the element in the output XML. (Read that sentence a few times if it doesn sink in right away!) Given what we know the output is supposed to look like, all thats left is to find the four data elements from this in the FileMaker XML, and output each one wrapped in a tag that correctly names its data field.

This is a little trickier because in the FileMaker XML, a contains only elements, with no mention of the actual field name in question. (You might recall that field names, in the FMPXMLRESULT output grammar, appear near the top of the document in the section.) We have to loop through all the elements inside the row, and for each one, we decide how to output it based on its position in the group.

Once again we use to loop over a set of elements, in this case all the elements inside the current . For each element we process, we need to make a choice as to how to output it. If its in the first position, we output it as an element; if its in the second position, we output it as a element, and so forth.

If we were trying to program this type of multiple choice in a FileMaker calculation, wed use a Case() statement, or perhaps a Choose(). Here we use the XSL equivalent, which is called . Like FileMakers Case statement, xsl:choose lets you choose among several options, each one corresponding to a logical test of some kind. The element contains one or more statements. Each one corresponds to a particular choice, and each choice is associated with a logical test. In the code we showed in the preceding section, the first test inside the element is the test for columns whose position equals 1. In this case, we go on to output the ... tag pair, with the data value inside it. To do this, we use the element, which can pull out a piece of the source XML document to output. In this case, each element in the FileMaker source XML has a element inside it, and its that element we want to grab and add to the output.

The rest of the statement contains the remaining tests, for the columns in positions 2, 3, and 4 of the output. At this point, we e done! The rest of the code consists of emitting closing XML tags that match the opening tags weve already sent, and of closing up our XSL constructs, like .

Applying an Export Transformation to FileMaker XML

FileMaker lets you use XSL stylesheets to transform your data when moving data into or out of FileMaker with XML. Lets consider the export example first. If you have a table of FileMaker data (such as the widget data weve been using), and you choose to export the data as XML, youll see the dialog box shown in Figure 22.6.

Figure 22.6. When exporting XML from FileMaker, you may also choose to apply a stylesheet to transform the outbound XML.

Here you can choose your XML export grammar, as weve already seen, but you can also choose whether to apply an XSL stylesheet to transform the XML as its being output. If you want to apply a stylesheet, you can pick a local file (in other words, a file resident on your local hard drive or on a mounted server volume). You can also pick a stylesheet file thats available over HTTP (namely, on a web server somewhere).

Working with Remote Stylesheets

The HTTP feature was a very smart choice on the part of FileMakers development team. Its very important in a multiuser FileMaker deployment, where many users use the same solution files hosted by a single server. If the only option for stylesheet use was to use a file from the users locally accessible hard drive or drives, youd either have to distribute the stylesheet to all system users and make sure that they put it in the right location on their hard drives, or youd have to have a common server volume that all users would have to mount. With the capability to pull a stylesheet from a web server, you can create one single stylesheet and place it on a central web server, and let it be accessed by all users.

One important qualification to this capability is that FileMaker currently supports remote access to stylesheets via only the HTTP protocol. HTTPS (secure HTTP) is not currently supported.

Using XSL stylesheets in the export process in this way, you can transform FileMaker data into a wide variety of output formats: other variants of XML, or HTML, or XML suitable for import into applications such as Excel or Quark Xpress, or even a complex text format such as PDF.

Категории