web analytics

<xsl:include> vs <xsl:import>

Options

codeling 1595 - 6639
@2016-12-22 10:57:57

The <xsl:include> and <xsl:import> instructions give you ways to incorporate XSLT stylesheets programmatically. Large, complex stylesheets, like large complex programs, are easier to maintain when you break them into modules with specific roles to play. In XSLT, the <xsl:include> and <xsl:import> instructions let you assemble the pieces. This modular approach also makes it possible to share parts of a stylesheet with other stylesheets that only want certain features and not the whole thing; they can just include or import the parts they need.

@2016-12-22 17:05:01

<xsl:include>

<xsl:include> means to include the referenced xsl document (b.xsl) within the referencing document (a.xsl). The XSLT processor replaces it with the contents of the stylesheet named in the href attribute. For example, the following makehtml.xsl stylesheet names the inlines.xsl stylesheet to incorporate that stylesheet:

<!-- makehtml.xsl -->

<xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"
     version="1.0">

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

  <xsl:template match="chapter">
   <html><xsl:apply-templates/></html>
  </xsl:template>

  <xsl:template match="para">
   <p><xsl:apply-templates/></p>
  </xsl:template>

  <xsl:template match="chapter/title">
   <h1><xsl:apply-templates/></h1>
  </xsl:template>

</xsl:stylesheet>

If inlines.xsl looks like this,

<!-- inlines.xsl -->

<xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"
     version="1.0">

  <xsl:template match="emphasis">
   <b><xsl:apply-templates/></b>
  </xsl:template>

  <xsl:template match="literal">
   <tt><xsl:apply-templates/></tt>
  </xsl:template>

</xsl:stylesheet>

the XSLT processor will treat makehtml.xsl as if it looked like

<xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"
     version="1.0">

  <xsl:template match="emphasis">
   <b><xsl:apply-templates/></b>
  </xsl:template>

  <xsl:template match="literal">
   <tt><xsl:apply-templates/></tt>
  </xsl:template>

  <xsl:template match="chapter">
   <html><xsl:apply-templates/></html>
  </xsl:template>

  <xsl:template match="para">
   <p><xsl:apply-templates/></p>
  </xsl:template>

  <xsl:template match="chapter/title">
   <h1><xsl:apply-templates/></h1>
  </xsl:template>

</xsl:stylesheet>

The complete inlines.xsl stylesheet didn't get inserted; its contents did. In other words, everything between its xsl:stylesheet tags (the stylesheet's "emphasis" and "literal" template rules) got inserted where the makehtml.xsl stylesheet had its xsl:include instruction.

The included stylesheet must still be a complete stylesheet.

An included stylesheet may in turn include other stylesheets, and they may include other stylesheets. There's no limit to the levels of inclusion that you can use, although the more you do it, the more complexity you have to keep track of.

The xsl:include element can go anywhere you want in a stylesheet, as long as it's a top-level element -- that is, a child of the xsl:stylesheet element that makes up the main body of the stylesheet. Putting an xsl:include instruction inside another element, such as an xsl:template template rule, wouldn't make sense, anyway; there would be no point to inserting another stylesheet's complete contents inside of a template rule.

Using xsl:include doesn't change XSLT's approach to multiple template rules that apply to the same node. If the XSLT processor can't find one template that is more specific than another for a particular source tree node, it's an error. Using xsl:include does increase the chance of this error happening, especially if you include stylesheets that include other stylesheets, because it's harder to keep track of the full collection of template rules being grouped together.

@2016-12-22 22:34:15

<xsl:import>

An XSLT file can import another XSLT file using an <xsl:import> element. Importing an XSLT file is the same as including it except that definitions and template rules in the importing file take precedence over those in the imported XSLT file. The <xsl:import> element has an href attribute whose value is a URI reference identifying the style sheet to be imported. A relative URI is resolved relative to the base URI of the <xsl:import> element.

The <xsl:import> element is allowed only as a top-level element. The <xsl:import> element children must precede all other element children of an <xsl:stylesheet> element, including any <xsl:include> element children. When <xsl:include> is used to include a style sheet, any <xsl:import> elements in the included document are moved up in the included document to follow any existing <xsl:import> elements in the included document.

The <xsl:stylesheet> elements encountered during processing of a style sheet that contains <xsl:import> elements are treated as forming an import tree. In the import tree, each <xsl:stylesheet> element has one import child for each <xsl:import> element that it contains. Any <xsl:include> elements are resolved before constructing the import tree. An <xsl:stylesheet> element in the import tree is defined to have lower import precedence than another <xsl:stylesheet> element in the import tree if it would be visited before that <xsl:stylesheet> element in a post-order traversal of the import tree (that is, a traversal of the import tree in which an <xsl:stylesheet> element is visited after its import children). Each definition and template rule has import precedence determined by the <xsl:stylesheet> element that contains it.

For example, assume the following conditions are true.

  • XSLT file A imports XSLT files B and C, in that order.
  • XSLT file B imports XSLT file D.
  • XSLT file C imports XSLT file E.

The order of import precedence (lowest first) is D, B, E, C, A.

For example, the following makehtml2.xsl stylesheet tells the XSLT processor to import the inlines.xsl stylesheet. The syntax is nearly identical to the use of xml:include; you name the imported stylesheet with the href attribute.

<!-- makehtml2.xsl -->

<xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"
     version="1.0">

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

  <xsl:template match="chapter">
   <html><xsl:apply-templates/></html>
  </xsl:template>

  <xsl:template match="para">
   <p><xsl:apply-templates/></p>
  </xsl:template>

  <xsl:template match="chapter/title">
   <h1><xsl:apply-templates/></h1>
  </xsl:template>

  <xsl:template match="emphasis">
   <i><xsl:apply-templates/></i>
  </xsl:template>

</xsl:stylesheet>

If inlines.xsl looks like this,

<!-- inlines.xsl -->

<xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"
     version="1.0">

  <xsl:template match="emphasis">
   <b><xsl:apply-templates/></b>
  </xsl:template>

  <xsl:template match="literal">
   <tt><xsl:apply-templates/></tt>
  </xsl:template>

</xsl:stylesheet>

the XSLT processor will treat makehtml2.xsl as if it looked like

<xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"
     version="1.0">

  <xsl:template match="emphasis">
   <i><xsl:apply-templates/></i>
  </xsl:template>

  <xsl:template match="literal">
   <tt><xsl:apply-templates/></tt>
  </xsl:template>

  <xsl:template match="chapter">
   <html><xsl:apply-templates/></html>
  </xsl:template>

  <xsl:template match="para">
   <p><xsl:apply-templates/></p>
  </xsl:template>

  <xsl:template match="chapter/title">
   <h1><xsl:apply-templates/></h1>
  </xsl:template>

</xsl:stylesheet>

The inlines.xsl stylesheet's "literal" template rule was added to the normalized makehtml2.xsl stylesheet, but the same stylesheet's "emphasis" template rule was ignored. Both makehtml2.xsl and inlines.xsl have template rules with a match pattern of "emphasis," and because inlines.xsl was imported and not included, an XSLT processor will use the one in makehtml2.xsl, not the one in inlines.xsl. The XSLT processor will add emphasis element nodes to the result tree surrounded by the i start- and end-tags shown in makehtml2.xsl and not by the b tags in the imported "emphasis" template rule in inlines.xsl.

@2017-09-15 11:49:19

This post demonstrates you how to use imports and includes to override XSLT templates by describing a style sheet that converts an XML announcement into HTML. The overall goal is to provide default templates, but to allow the user enough latitude to change certain aspects of the style sheet if desired. Other aspects are not changeable. The style sheets work with the following source document:

Listing 1. The source document

<?xml version="1.0"?>

<?xml-stylesheet href="style.xsl"

version="1.0"

    type="text/xsl"?>

<announcement>

 <headline>Contest Announcement</headline>

 <description>

   Do you love

   <product>Pop's Homemade Mashed Potato Mix</product>?

   Are you artistic?  Well, here's your big big chance! 

   Loopy Foods, the company that brings you

   <product>Pop's Homemade Mashed Potato Mix</product>

   and <product>Aunt Susie's Squash in a Box</product>

   is hosting a Mashed Potato Sculpting Contest.  Send your

   entry today.  Contest rules are on the back of every box

   of <product>Pop's Homemade Mashed Potato Mix</product>.

 </description>

 <copyright/>

</announcement>

The goal is to create an HTML page with a style sheet such as this:

Listing 2. The basic style sheet

<?xml version="1.0"?>

 

<xsl:stylesheet version="1.0"

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

 

<xsl:template match="/">

<html>

    <head><title><xsl:value-ofselect"announcement/headline"/></title></head>

    <body>

       <xsl:apply-templates/>

    </body>

</html>

</xsl:template>

 

<xsl:template match="headline">

    <h1><xsl:apply-templates/></h1>

</xsl:template>

 

<xsl:template match="description">

    <p><xsl:apply-templates/></p>

</xsl:template>

 

<xsl:template match="product">

    <b><xsl:apply-templates/></b>

</xsl:template>

 

</xsl:stylesheet>

The result is a document that creates a paragraph for each announcement, and puts the product names in bold:

Listing 3. The basic transformation results
 

Creating the template style sheet

Using these templates, an administrator can build a basic style sheet that enables users to use default styles, but allows them to use custom styles if necessary. To do this, you need to include the basic templates in a second style sheet, in this case called import.xsl:

Listing 4. The imported style sheet (import.xsl)

<?xml version="1.0"?>

 

<xsl:stylesheet version="1.0"

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

 

<xsl:template match="headline">

    <h1><xsl:apply-templates/></h1>

</xsl:template>

 

<xsl:template match="description">

    <p><xsl:apply-templates/></p>

</xsl:template>

 

<xsl:template match="product">

    <b><xsl:apply-templates/></b>

</xsl:template>

 

</xsl:stylesheet>

From there, it's a matter of creating a style sheet that imports the main styles. With this import in place, a style sheet that contains only the main template still acts as desired, but if an additional template is added, it overrides the corresponding template in the import:

Listing 5. Overriding imported templates

<?xml version="1.0"?>

 

<xsl:stylesheet version="1.0"

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

 

<xsl:template match="/">

<html>

    <head><title><xsl:value-of select"announcement/headline"/></title></head>

    <body>

       <xsl:apply-templates/>

    </body>

</html>

</xsl:template>

 

<xsl:template match="headline">

    <h1><xsl:apply-templates/></h1>

</xsl:template>

 

<xsl:template match="description">

    <p><xsl:apply-templates/></p>

</xsl:template>

 

<xsl:template match="product">

    <b><xsl:apply-templates/></b>

</xsl:template>

 

</xsl:stylesheet>

Imported style sheets have a lower precedence than the main style sheet, so the product template in the main style sheet is used instead of the imported product template:

Listing 6. Overridden template results

Even when a template is overridden, you still have the opportunity to use the imported templates, however, using the apply-imports option:

Listing 7. Applying imports

...

</html>

</xsl:template>

 

<xsl:template match="product">

    <i><xsl:apply-imports/></i>

</xsl:template>

 

</xsl:stylesheet>

As a result, both the original template and the imported template are executed:

Listing 8. Using overridden templates
 

The difference between importing and including

An import element must always be a top-level element, and must always come before any other elements. This requirement has a specific consequence in terms of precedence. In an XSLT style sheet, the last template processed has precedence over everything that has come before, so imported templates are always overridden. Imported templates also become part of the import tree, so they're available for the apply-imports element.

On the other hand, style sheets can also be included using the include element, which simply adds them to the main style sheet at the point in which they're included. What's more, while a style sheet must be included at the top level, it can be added at any point, so it can easily be added at the bottom of the page, overriding any templates the user might add.

For example, you could create an included style sheet that sets the copyright information, called include.xsl:

Listing 9. The included style sheet (include.xsl)

<?xml version="1.0"?>

 

<xsl:stylesheet version="1.0"

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

 

<xsl:template match="copyright">

     <p>Copyright 2003, Loopy Foods</p>

</xsl:template>

 

</xsl:stylesheet>

When this style sheet is included at the end of the main style sheet, it overrides any other templates:

Listing 10. Including the style sheet

...

<xsl:template match="product">

    <i><xsl:apply-imports/></i>

</xsl:template>

 

<xsl:template match="copyright">

    <p><big>Copyright now, by ME</big></p>

</xsl:template>

 

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

 

</xsl:stylesheet>

So even though the main style sheet includes a copyright template, the included template is still used:
Listing 11. Inclusion results
...
       Sculpting Contest.  Send your entry today. Contest rules are on the
       back of every box of <i><b>Pop's Homemade Mashed Potato Mix</b></i>.
    </p>
 
<p>Copyright 2003, Loopy Foods</p>
 
</body>
</html>

Remember that the precedence is a matter of position; if the style sheet (include.xsl) had been included at the start of the main style sheet rather than the bottom, the copyright template in the main stylesheet (style.xsl) would have been used instead.

Comments

You must Sign In to comment on this topic.


© 2024 Digcode.com