Specializing your stylesheets with xsl:import

SDN member Morten Wittrock demonstrates how to create a slight variation on an existing SAP mapping program without copying the entire program and modifying the copy.

This Content Component encountered an error
Introduction

XSLT has a very powerful and cool feature that doesn't seem to be that well known: The ability to import other stylesheets into the stylesheet you're working on. Why is this a big deal, you ask? Mainly because it presents an elegant solution to an oft seen problem: How to create a slight variation on an existing mapping program without copying the entire program and modifying the copy.

What was the problem again?

Imagine a scenario in which you want to deliver electronic invoices to your customers. You've created a mapping program that transforms an INVOIC02 IDoc into an XML format. Everything works smoothly, until one day a new, important customer requests a slight change to the element:

<InvoicingParty>
    <VendorNumber>01061854</VendorNumber>
    <VendorName>Watson and Holmes Enterprises</VendorName>
    <VendorAddress>
        <Street>221b Baker Street</Street>
        <City>London</City>
        <PostalCode>NW1 6XE</PostalCode>
    </VendorAddress>
</InvoicingParty>

The customer requests that the vendor's name and number be combined into a single element:

<InvoicingParty>
    <Vendor number="01061854">Watson and Holmes Enterprises</Vendor>
    <VendorAddress>
        <Street>221b Baker Street</Street>
        <City>London</City>
        <PostalCode>NW1 6XE</PostalCode>
    </VendorAddress>
</InvoicingParty>

XSLT to the rescue

What we'd like to do is create a new mapping program that is a specialization of the existing one. In object-oriented terms, we'd like to inherit the parent program's functionality and override a small subset of it. Using message mapping, such specialization is not possible and we'd have to resort to copying the entire mapping program and modifying the copy. Using XSLT, however, specialization is not only possible, but also very simple to implement.

The following is a snippet of the Invoice_general.xsl stylesheet, which transforms an entire INVOIC02 IDoc into the invoice XML format. Specifically, the template shown is responsible for creating the invoice header:

<xsl:template name="InvoiceHeader">
    <Header>
        <InvoiceNumber>....</InvoiceNumber>
        <InvoiceDate>....</InvoiceDate>
        <Currency>....</Currency>
        <!-- Lots of other header information goes here -->
        <xsl:call-template name="InvoicingParty"/>
    </Header>
</xsl:template>

Notice that the template doesn't know how to format the invoicing party. Instead, it delegates that task to the InvoicingParty template:

<xsl:template name="InvoicingParty">
    <xsl:variable name="party" select="/INVOIC02/IDOC/E1EDKA1[PARVW='RS']"/>
    <InvoicingParty>
        <VendorNumber>
            <xsl:value-of select="$party/LIFNR"/>
        </VendorNumber>
        <VendorName>
            <xsl:value-of select="$party/NAME1"/>
        </VendorName>
        <VendorAddress>
            <Street>
                <xsl:value-of select="$party/STRAS"/>
            </Street>
            <City>
                <xsl:value-of select="$party/ORT01"/>
            </City>
            <PostalCode>
                <xsl:value-of select="$party/PSTLZ"/>
            </PostalCode>
        </VendorAddress>
    </InvoicingParty>
</xsl:template>

Using XSLT templates we've managed to pinpoint exactly where to implement the customer's request. We still haven't seen how to actually implement it, though.

Adding the xsl:import magic

Using the XSLT <xsl:import> element, we can import another stylesheet into the stylesheet we're working on. The true power of this feature lies in the fact that templates in the imported stylesheet can be overriden by templates in the importing stylesheet. Here's a complete stylesheet that implements the customer's request:

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

    <xsl:import href="Invoice_general.xslt"/>

    <xsl:template name="InvoicingParty">
        <xsl:variable name="party" select="/INVOIC02/IDOC/E1EDKA1[PARVW='RS']"/>
        <InvoicingParty>
            <Vendor number="{$party/LIFNR}">
                <xsl:value-of select="$party/NAME1"/>
            </Vendor>
            <VendorAddress>
                <Street>
                    <xsl:value-of select="$party/STRAS"/>
                </Street>
                <City>
                    <xsl:value-of select="$party/ORT01"/>
                </City>
                <PostalCode>
                    <xsl:value-of select="$party/PSTLZ"/>
                </PostalCode>
            </VendorAddress>
        </InvoicingParty>
    </xsl:template>

</xsl:stylesheet>

The new stylesheet, Invoice_specific.xsl, imports the general stylesheet and implements only the single template that's needed to accommodate the customer's request. The same result could have been achieved by making a physical copy of the general stylesheet and modifying the InvoicingParty template. That would lead to potentially massive amounts of duplicated code, though. The proposed solution contains no duplicated code whatsoever. The specialized stylesheet is also very compact and it's immediately obvious how it extends the general stylesheet. Furthermore, bug fixes and improvements in the general stylesheet will automatically trickle down to the specialized stylesheet.

Final thoughts

In my opinion, the element belongs in the toolbox of every XSLT developer. It offers a powerful and clean solution to a problem often faced by XI developers, namely creating a variation on an existing mapping program without resorting to copying it and modifying the copy. For more information on the element, please refer to the "Stylesheet Import" section of the W3C XSLT 1.0 recommendation.


This content is reposted from the SAP Developer Network.
Copyright 2006, SAP Developer Network

SAP Developer Network (SDN) is an active online community where ABAP, Java, .NET, and other cutting-edge technologies converge to form a resource and collaboration channel for SAP developers, consultants, integrators, and business analysts. SDN hosts a technical library, expert blogs, exclusive downloads and code samples, an extensive eLearning catalog, and active, moderated discussion forums. SDN membership is free.

Want to read more from this author? Click here to read Morten Wittrock's weblog. Click here to read more about SAP Exchange Infrastructure (XI) on SDN.



This was first published in September 2006

Dig deeper on SAP PI-XI

Pro+

Features

Enjoy the benefits of Pro+ membership, learn more and join.

0 comments

Oldest 

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

-ADS BY GOOGLE

SearchManufacturingERP

SearchOracle

SearchDataManagement

SearchAWS

SearchBusinessAnalytics

SearchCRM

SearchContentManagement

SearchFinancialApplications

Close