7.2 Top-level Elements in XSL

7.2 Top-level Elements in XSL

The Extensible Stylesheet Language is a transformation and formatting language that uses specific child elements to transform an XML document. Some of these elements may only be used at the topmost level in the XSL document. These top-level elements are listed here:

Import—The element <xsl:import> is an empty element and has one attribute, href. The value of the href attribute is a URI pointing to the location of another stylesheet to be imported into the calling stylesheet. This element may not work in all browsers but shows the ability to make modular stylesheets and import as needed. Multiple stylesheets may be imported. Care must be taken when using imported stylesheets; the rules of the imported stylesheet take precedence over the internal rules.

<xsl:import href="anotherTemplate.xsl" />

Include—Like the <xsl:import> element, the top-level element <xsl:include> has one attribute, href, and is an empty element. However, it differs from the <xsl:import> element because a copy of an external stylesheet is placed in the document. The precedence of the rules for an included stylesheet is the same as the internal document rules. This element may not function properly, depending upon the browser.

<xsl:include href="anotherRule.xsl" />

Strip Space—This top-level element, <xsl:strip-space elements= "listOfElements" />, may not work in all browsers. The value for the elements attribute is a space-delimited list of elements in the document that need to explicitly have white space removed. White space is spaces, horizontal tabs, carriage returns, and linefeeds. Table 1.2 shows the white space characters. Listing 7.5 shows the XSL used with a FileMaker Pro 6 export. The return as the final character in some of the fields was converted to LF (linefeed) but was not stripped from the result. The use of the function normalize-space() will remove this character, as shown in this chapter.

<xsl:strip-space elements="DATA" />
Listing 7.5: stripSpace.xsl
Start example
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/
  Transform" xmlns:fm="http://www.filemaker.com/fmpxmlresult" >
<xsl:strip-space elements="fm:DATA" />
<xsl:template match="/">
<xsl:copy-of select="fm:FMPXMLRESULT" />
End example

Preserve Space—The empty element <xsl:preserve-space elements="listOfElements" /> works just the opposite of the strip-space element. The space-delimited list of elements in the attribute will have all white space preserved. This element may not process correctly in all browsers.

<xsl:preserve-space elements="bigField valueList" />

Key—Elements in the XML document may have unique identifiers. Elements may also cross-reference each other. The <xsl:key> element has the required attributes name (the name of the key), match (a pattern or node containing the key), and use (an expression, the value of the key). This element may be used by the XSLT function key(keyName, object).

For example, the ROW element in the FMPXMLRESULT and the FMPDSORESULT both use the attributes MODID and RECORDID. The MODID may help tell you what records have changed since you last retrieved the data. The RECORDID is the unique identifier for each record in a database. The key for each ROW (record) could be the RECORDID. Set the key in your XSL top-level elements. Some examples are shown here:

<xsl:key name="recID" match="//ROW" use="@RECORDID" />
<xsl:key name="unique" match="//ROW use="attribute::RECORDID" />

Once the key is declared, it can be used throughout the document. The following example uses the key with a static or predetermined value. This value could be obtained dynamically, as the stylesheet processes the XML from the top down. A good example for using the xsl:key and the key() function can be found in the stylesheet subsummary.xsl. This document is found in the FileMaker Pro 6 folder FileMaker Examples\ XML Examples\Export.

key('recID', '12345')
key('unique', '342')

Decimal Format—When numbers are used in an XSL stylesheet, there are defaults for how the number is formatted in the result, but these may be changed with the <xsl:decimal-format> top-level element. Multiple formats may be declared, so the first required attribute is name. The other attributes have these defaults: decimal-separator (the period character), grouping-separator (the comma character), infinity (a string "infinity", may be "8"), minus-sign, NaN (the string "NaN" for not a number), percent (the % character), per-mille ( or #x2030), zero-digit (0), digit (#), and pattern-separator (;).

This format is used by the function format-number(number, pattern, decimal-formatName).

<xsl:decimal-format name="phone" digit="x" />
<xsl:value-of select="format-number(NumberField, "(xxx) xxx-xxxx",
  phone) />

Namespace Alias—The default output of the result tree uses the namespaces in the source tree. If, for example, you want a template to use namespace declaration for the result tree and do not want to confuse the XSL processor, use this top-level element. The attribute stylesheet-prefix has the value of the prefix name or "#default". The attribute result-prefix has the value of the prefix name or "#default". Remember that the namespaces used in a document must be unique.

<xsl:namespace-alias stylesheet-prefix="fm2" result-prefix="fmp" />

The result tree will use the correct namespace if you use the alias in the XSL document.

Attribute Sets—Sometimes an XSL document will use a standard set of attributes for the result element. For example, you may wish to use the same text style attributes, but want to avoid entering them multiple times in the XSL stylesheet. Or maybe you want to have a convenient way to change an attribute set at the beginning of the document and have the styles apply throughout the document without a find and replace routine. The top-level element <xsl:attribute-set> may be used multiple times in the XSL document to create many sets. The required attribute for this element, name, is the name of the set. The element has another attribute that allows it to use other attribute sets, use-attribute-sets. You can specify a white space-separated list of other sets. The element can have a child element <xsl:attribute>. When you use the attribute use-attribute-sets with <xsl:element>, <xsl:copy>, or <xsl:attribute-set>, it will apply the attributes to those elements as if you entered them manually.

<xsl:attribute-set name="myStyles">
      <xsl:attribute name="font">Arial, Helvetica,
      <xsl:attribute name="size">12</xsl:attribute>
<xsl:element name="p" use-attribute-sets="myStyles"></xsl:element>

This XSL element is useful for creating FIELD elements in the METADATA element if you import XML. The FIELD elements all have the attributes EMPTYOK, MAXREPEAT, NAME, and TYPE. The NAME attribute element will be different for every field, but the other attributes may be the same and have no impact on the import. The example below creates an attribute set for the FIELD element:

<xsl:attribute-set name="fields">
      <xsl:attribute name="EMPTYOK">YES</xsl:attribute>
      <xsl:attribute name="MAXREPEAT">1</xsl:attribute>
      <xsl:attribute name="TYPE">TEXT</xsl:attribute>

Variables—Two XSL elements can be used to pass variables. They can be used as top-level elements or within the templates. Only top-level declarations can be used throughout the document. <xsl:variable> has the attributes name (required) and select (value of the variable). The variable is used by using the "$" symbol before the variable name in any expression. The <xsl:param> element allows a default value to be used if none is supplied. The <xsl:param> element also has two attributes, name and select.

Variables may be passed to templates with the <xsl:with-param> element in apply-templates, call-template. The <xsl:with-param> element has the same two attributes for all variables, name and select. The <xsl:with-param> element is never used as a top-level element. The value within the curly braces ({ and }) is evaluated before further processing.

<xsl:variable name="myVar" select="Literal" />
<xsl:param name="myParam" select="default" />
<xsl:value-of select="{$myVar}" />
      <xsl:with-param name="sendThis" />

Output—The result tree can be formatted correctly using the top-level element <xsl:output>. This element is always empty but may be used multiple times in the top of the XSL document. The attribute method values may be "xml", "html", or "text". The final device for output may treat each of these methods differently. An attribute version="1.0" is included for forward compatibility. The encoding of the result document may be specified with the encoding attribute. The value of encoding is a string with the charset found in RFC2278 or begins with "x-". By default the result tree may be encoded as UTF-16 or Unicode. You can read about these language encodings in section 1.42, "Unicode vs. ASCII."

Other attributes for <xsl:output> are omit-xml-declaration (values may be "yes" or "no"), standalone (values may be "yes" or "no"), doctype-public (value may be a string with the name of the public doctype), and doctype-system (value may be a string with the name of the internal doctype). The attribute indent will format the result tree with indented child elements if this value is "yes" and media-type is the value of the MIME content type of the result. If method="text", the attribute media-type may have the value "text/plain".

<xsl:output method="html" version ="1.0" encoding="us-ascii"
  indent="yes" />

The attribute cdata-section-elements lists the elements in the document that need to be CDATA in the output. CDATA allows entities to be passed from the source to the result without parsing. For example, you may have HTML within a field and need to pass the code as raw text without converting the "<" to "&lt;" or ">" to "&gt;".

Templates—The final top-level element, <xsl:template>, deserves its own section in this chapter (see the following). The XSL stylesheet is template-based and may have internal templates or external templates (inserted with <xsl:import> and <xsl:include> elements).

7.21 XSL Templates

After all the other top-level elements are declared, the basic stylesheet uses the element <xsl:template> to set up rules for using or not using the elements from the source document. The <xsl:template> element has the attribute match to test for a section of the XML. Usually, the match value is an XPath expression or pattern. Since every document has a root, the XPath shortcut "/" can be used as the match for any document where the elements are unknown. Once a match is made, the contents of the template are used to find more rules, display the result of the match, or return literal text to the result tree. All the other XSL elements are used within the templates. The variables <xsl:variable> and <xsl:param> may also be used within a template.

<xsl:template match="/">
      Every well-formed XML document has a root.<br />
      This basic template will display for every

The template rule is recursive and will match every pattern or XPath within the current node. For example, the FMPXMLRESULT grammar will return a ROW element for every record in a found set. Any template rule for match="fm:ROW" will apply to all the records (or ROW elements) in the XML document. You can further specify the match with predicates in the XPath express that indicate a match for a ROW with a unique ID, an attribute value, or the position in the document.

      <!-- first record only -->
<xsl:template match="fm:ROW[1]">
      <!-- only the record with the ID of 3758 -->
<xsl:template match="fm:ROW/@RECORDID=3758">
      <!-- the last record -->
<xsl:template match="fm:ROW[last()]">

The <xsl:template> element can also be used to set up a named template. Templates may be called as needed in an XSL document. The attribute name has the unique name of a template. Rules are set up inside the named template just as for the match template. The element <xsl:call-template name="UniqueName" /> can be used anywhere in the XSL document to branch to the named template.

XSL templates are very similar to FileMaker Pro scripts. You can even have subscripts in other documents! The top-level elements <xsl:include> and <xsl:import> are used to bring in the template rules from other sources.

<xsl:call-template name="myRules" />
<xsl:template name="myRules">
      When you call this template, it will bring its
      rules with it.

XSL templates are also like a FileMaker Pro layout. If you have layout with the view set to list, you only place the fields, layout labels, graphics, and other elements in the body part. These elements are repeated for every record in the found set. The values in the fields may change, but the rules for applying the values and the rules for displaying the elements are the same for each record. Form View layouts also "repeat" because you do not have to create a layout for each record. You do not need to use every field on every layout. The XSL template does the same for each match, only setting rules for the elements it contains. You can combine the templates to view only the data you need, just like the fields on the layout.

Default Templates—Many XSL processors, including browsers, have built-in templates. These may be implied and are not necessary to explicitly declare. When the <xsl:template match="*|/"> is used, for any element (*) or the root element (/), the default rule is to apply any other templates in the XSL stylesheet.

<xsl:template match="*|/">
      <xsl:apply-templates />

The use of the empty element <xsl:apply-templates /> is implied. If a rule is not within a template, the XSL processor should look for more templates. However, <xsl:apply-templates> should be used to make the XSL document more easily understood by all processors.

Some other default templates are for modes, attributes, processing instructions, and comment elements. The default match for any element or the root with a particular mode passes on to apply any other templates for the same mode. The template that matches any text node or any attribute (@*) will default to use the value of the text node or the attribute. Processors often ignore the processing instructions and comments if there are no template rules set up for them. These defaults are shown below:

<!-- for modes -->
      <xsl:template match="*|/" mode="myMode">
            <xsl:apply-templates mode="myMode" />
<!-- for attributes -->
      <xsl:template match="text()|@*">
            <xsl:value-of select="." />
<!-- p.i. and comments -->
      <xsl:template match="processing-instruction()|comment()" />

Template Mode—The mode attribute can be used to allow an element to be processed multiple times in a stylesheet. Otherwise, the source tree is processed once for every element in the XML document. The mode attribute is only used with the match attribute and is declared in the <xsl:template> element and the <xsl:apply- templates> element.

Apply Other Templates—The default rule is to continue processing an XML document until all matches have been made. This element, <xsl:apply-templates />, is implied but should be included if conditional branching is used. The attribute select is used to name a particular XPath of the document to be processed. The mode attribute can also be used with the <xsl:apply-templates> element. Both attributes are optional and if none is included, the processor continues to search for other templates. The <xsl:apply-templates> element can be empty or may contain the elements <xsl:sort> or <xsl:with-param>.

<xsl:apply-templates />
      <xsl:sort />
<xsl:apply-templates select="fm:ROW" />

Use a Named Template—The branch to a named template uses the <xsl:call-templates> element. The required attribute for this element is name and has the value of the named template for the branch. This element can be empty or use the <xsl:with-param> child element between the start and end tags.

<xsl:call-template name="myRules">
      <xsl:with-param />
<xsl:call-template name="yourRules" />

Pass Parameters to Templates—The element <xsl:with-param> can be used with the <xsl:apply-templates> and <xsl:call-template> elements, as shown above. This element has two attributes, the name of the parameter and the select attribute, which is the value of the parameter to pass. The name of the parameter matches a declared <xsl:param> element in the top level or within the same template.

<xsl:param name="myDefault">abc</xsl:param>
      <xsl:with-param name="myDefault">def</xsl:with-param>
<!-- this has just changed the default value for the parameter
  "myDefault" -->
<!-- had none been specified, the original parameter would have been
  used -->

Apply Imported Templates—Another way to change the rules for a template is to use the top-level <xsl:apply-imports> element. This element is always empty and has no attributes or child elements. It is used only inside a stylesheet that has at least one <xsl:import> element.

Templates use other XSL elements to process the source tree and transform it into the result tree. These elements are fully explained in the W3C document "XSL Transformations (XSLT), Version 1.0," http://www.w3.org/TR/xslt. Brief examples of the more common elements are presented in the following section.