Dynamically reusing XSLT templates across XSL files

Discussion in 'XML' started by Vince C., Jul 2, 2003.

  1. Vince C.

    Vince C. Guest

    Hi all,

    I've created XML documents that are described with a schema. I'm using those
    documents to create web pages.

    All my web pages contain a fixed header and a variable document part. The
    header is the same in each page and is described in an XML document,
    "Head.xml". The document part, which is variable in content, is described in
    other XML files (e.g. "Document.xml", "Product.xml", "Register.xml").

    Following the liquid design way, a web page is always built from "Head.XML"
    and (only) one XML document. A page is always made of a succession of DIV
    elements that are positioned using CSS. A DIV corresponds to a piece of
    information in the schema.

    I defined the base structure of a document in a schema and I wanted that
    structure to be extensible. Hence I've extended the definition of a document
    to fit other requirements (e.g. form submission documents - "Register.xml",
    product sheet - "Product.xml").

    For instance, static information contain a title and a body text. The title
    and the text form the base document in "Document.xml". A product document,
    "Product.xml", extends the base document definition to add a list of
    packages. Packages are also rendered in HTML as a DIV below the body text.

    The XSL templates required to output a page HTML, HEAD, BODY and document
    header are placed in an XSL file, "Head.xsl". The XSL templates to output a
    document are placed in another XSL file, "Document.xsl". The templates to
    output a product are placed in yet another XSL file, "Product.xsl".

    How can I reuse those templates given that the template that outputs the
    structure of the web page must be called first?

    A concrete case: to output the web page for a document, I need to call some
    templates in "Head.xsl", plus some other templates in "Document.xsl" that
    should be called in-between. If I want to output the page for a product I
    have to call the same templates from "Head.xsl", that should in turn call
    some templates from "Document.xsl" (to render title and text) and finally
    call some templates from "Product.xsl" (to render packaging below the text).

    Such an order in calls is required because the template that renders the
    structure of a page also renders the HTML and BODY elements. So I have to
    call templates dynamically from within "Head.xsl".

    Is there a smart(er) way to achieve this?

    Thanks for any hint/suggestion.

    Vince C.
    Vince C., Jul 2, 2003
    #1
    1. Advertising

  2. Vince C.

    Vince C. Guest

    Thanks a lot, Colin.

    See my comments below.

    "Colin Mackenzie" <> a écrit dans le message de news:
    bduu5b$e7s$...
    > Hi,
    >
    > I am not sure I fully understand your requirement but here goes,
    >
    > why not do as follws
    >
    > 1/ transform the XML using Document.xsl/products.xsl etc as required
    > depending on the type of page
    > 2/ ensure that BOTH document and product XSL include or import head.xsl (see
    > xsl:include)
    > 3/ ensure that the match for the root or document element of the XML exists
    > only in the head.xsl thus
    > a) when the root/document element is matched the <html<body> elments are
    > output
    > b) inside the body tag have an apply-tempaltes (to allow the contents to be
    > processed by a matched template)
    > c) when the content is matched (by the appropriate match in the appropraite
    > stylesheet) the content is output
    >
    > Does this match your requirement?


    Perfectly.

    In fact, I took a deeper look to <xsl:import>. As you pointed out, it does
    everything I want provided <xsl:apply-templates> is used whenever applicable. I
    never used XSL imports before so I made a test with a couple of XML and XSL
    files.

    I created an XML file with 2 elements: "a" and "b". I then created 2 XSL files:
    "A.xsl" and "B.xsl". The former contained a template for element "a" and the
    main HTML template, the latter contained only a template for element "b" plus an
    import of template "B.xsl". I transformed the XML using "B.xsl" and all
    templates were called.

    -- Test.xml --
    <?xml version="1.0" encoding="UTF-8"?>
    <?xml-stylesheet type="text/xsl" href="B.xsl"?>
    <root>
    <a>First element</a>
    <b>Second element</b>
    </root>

    -- A.xsl --
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" exclude-result-prefixes="xsl fo"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <xsl:template match="a">
    <p>This is element <b>A</b>: <i>"<xsl:value-of select="text()"/>"</i></p>
    </xsl:template>

    <xsl:template match="/">
    <html>
    <head>
    <title>Dynamic Templates Test Page</title>
    </head>
    <body>
    <xsl:apply-templates select="/root"/>
    </body>
    </html>
    </xsl:template>
    </xsl:stylesheet>

    -- B.xsl --
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" exclude-result-prefixes="xsl fo"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <xsl:import href="A.xsl"/>
    <xsl:template match="b">
    <p>This is element <b>B</b>: <i>"<xsl:value-of select="text()"/>"</i></p>
    </xsl:template>
    </xsl:stylesheet>

    -- Output --
    This is element A: "First element"

    This is element B: "Second element"
    ----

    Ok, I've clearly discovered (Smirnoff Ice?) the <xsl:import> mechanism... But I
    now realize its power: it's as flexible as Object Oriented Programming when you
    override classes and create polymorphic containers.

    Importing templates is just like deriving classes in C++: you can reuse
    templates on documents that you didn't design just by importing the existing
    ones into new stylesheets. All you have to do is provide templates for new
    elements in the instance file or redefine existing templates.

    This gives the same flexibility as deriving classes and overriding member
    functions. As you also pointed out the structure of stylesheets and documents is
    also important.

    To bring a complete solution to my puzzle, I can put a reference to "Head.xml"
    in "Document.xsl" using the document() function. If I import "Document.xsl" in
    every subsequent stylesheet, everything should be fine.

    Thanks a lot for again your help,
    Vince C.
    Vince C., Jul 2, 2003
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Vijay singh
    Replies:
    1
    Views:
    430
    Martin Honnen
    Nov 4, 2004
  2. JKop
    Replies:
    3
    Views:
    454
  3. recover
    Replies:
    2
    Views:
    789
    recover
    Jul 25, 2006
  4. Niranjan

    Reusing web user controls across application

    Niranjan, Aug 17, 2003, in forum: ASP .Net Building Controls
    Replies:
    5
    Views:
    148
    Teemu Keiski
    Aug 18, 2003
  5. Brian

    Reusing Parameters across web methods

    Brian, Feb 27, 2004, in forum: ASP .Net Web Services
    Replies:
    1
    Views:
    133
    Dan Rogers
    Nov 11, 2004
Loading...

Share This Page