RE: [xsl] decorator / wrapper design pattern

Subject: RE: [xsl] decorator / wrapper design pattern
From: "Schaik, L.B. van" <L_B_van_Schaik@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 23 Mar 2005 09:13:38 +0100
Hi,

To conclude this thread I want to thank everybody who helped (Stef, Jay,
Wendell) very much and give the solution I've chosen. Below is the XML
and XSLT I've created this far (it is not ready yet, it needs some
tweaking), because it are big files I've left some things out and
replaced them with '...' or '<!-- ... -->'.
Context: The XML is created by our library system called Aleph every
time someone prints orders (this is a test XML file), then the XML is
transformed to (X)HTML via an XSL file.
There are more than 20 other prints to be made, so I want to have some
general purpose functions for page layout.

XML:
<?xml version="1.0"?>
<printout>
<form-name>acq-order-list</form-name>
<form-language>NED</form-language>
<form-format>00</form-format>
<subject>Acq order list</subject>

<section-01>
<form-date>07/02/2005</form-date>
<!-- ... -->
<z72-vendor-tel>532 ...</z72-vendor-tel>
<z72-vendor-fax>516 ...</z72-vendor-fax>
<z72-vendor-em>mailbox@....nl</z72-vendor-em>
<z72-vendor-ip></z72-vendor-ip>
<z72-vendor-address-occ1>... Vereniging Leiden</z72-vendor-address-occ1>
<z72-vendor-address-occ2>P.O.B. ...</z72-vendor-address-occ2>
<z72-vendor-address-occ3>... LEIDEN</z72-vendor-address-occ3>
<z72-vendor-address-occ4></z72-vendor-address-occ4>
<z72-vendor-address-occ5></z72-vendor-address-occ5>
<z72-vendor-address-occ6></z72-vendor-address-occ6>
<z72-vendor-address-occ7></z72-vendor-address-occ7>
<!-- ... -->
<z70-note>Rush delivery</z70-note>
<!-- ... -->
</section-01>


<section-02>
<bib-info>## Klugt, Peter van der 1956-## Een zinderende avond / Peter
van der Klugt## Amsterdam : Prometheus#### 265 p ; 20 cm</bib-info>
<!-- ... -->
<z68-doc-number>785998</z68-doc-number>
<z68-sequence>8</z68-sequence>
<z68-order-type>Monograph</z68-order-type>
<z68-order-number>1058</z68-order-number>
<!-- ... -->
<z68-open-date>07/02/2005</z68-open-date>
<z68-order-status>Ready to send to vendor</z68-order-status>
<z68-order-status-date>07/02/2005</z68-order-status-date>
<!-- ... -->
<z68-sub-library>Vakgroep Geschiedenis</z68-sub-library>
<!-- ... -->
<z68-order-date></z68-order-date>
<!-- ... -->
<z68-vendor-code>01BWT</z68-vendor-code>
<!-- ... -->
<z68-vendor-note>Rush order</z68-vendor-note>
<z68-no-units>1</z68-no-units>
<z68-unit-price>1.00</z68-unit-price>
<z68-total-price>1.00</z68-total-price>
<z68-e-currency>EURO</z68-e-currency>
<z68-e-listed-price>1.00</z68-e-listed-price>
<z68-e-price>1.00</z68-e-price>
<z68-e-local-price>1.00</z68-e-local-price>
<!-- ... -->
<z68-ordering-unit>UB Acquisitie</z68-ordering-unit>
<budget-number-1>01-904-1-2005</budget-number-1>
</section-02>

<section-02>
<bib-info>## Klugt, Peter van der 1956-## Een zinderende avond / Peter
van der Klugt## Amsterdam : Prometheus#### 265 p ; 20 cm</bib-info>
<!-- ... -->
<z68-doc-number>785998</z68-doc-number>
<z68-sequence>8</z68-sequence>
<z68-order-type>Monograph</z68-order-type>
<z68-order-number>1058</z68-order-number>
<!-- ... -->
<z68-open-date>07/02/2005</z68-open-date>
<z68-order-status>Ready to send to vendor</z68-order-status>
<z68-order-status-date>07/02/2005</z68-order-status-date>
<!-- ... -->
<z68-sub-library>Vakgroep Geschiedenis</z68-sub-library>
<!-- ... -->
<z68-order-date></z68-order-date>
<!-- ... -->
<z68-vendor-code>01BWT</z68-vendor-code>
<!-- ... -->
<z68-vendor-note>Rush order</z68-vendor-note>
<z68-no-units>1</z68-no-units>
<z68-unit-price>1.00</z68-unit-price>
<z68-total-price>1.00</z68-total-price>
<z68-e-currency>EURO</z68-e-currency>
<z68-e-listed-price>1.00</z68-e-listed-price>
<z68-e-price>1.00</z68-e-price>
<z68-e-local-price>1.00</z68-e-local-price>
<!-- ... -->
<z68-ordering-unit>UB Acquisitie</z68-ordering-unit>
<budget-number-1>01-904-1-2005</budget-number-1>
</section-02>

<section-03>
<total-currency>EURO</total-currency>
<total-price>2.00</total-price>
<total-price-euro>2.00</total-price-euro>
<total-no-units>2</total-no-units>
</section-03>

</printout>




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

<xsl:template match="/">
  <xsl:call-template name="body"/>
</xsl:template>

<xsl:template match="section-02">
  <xsl:call-template name="page">
    <xsl:with-param name="contents">
      <xsl:call-template name="align-right">
        <xsl:with-param name="contents">
          <H2>Universiteitsbibliotheek</H2>
          <H3>Afd. Acquisitie</H3>
        </xsl:with-param>
      </xsl:call-template>
      <xsl:call-template name="vendor-address"/>
      <xsl:call-template name="paragraph">
        <xsl:with-param name="contents">
           <B>Gelieve te leveren:</B>
        </xsl:with-param>
      </xsl:call-template>
      <xsl:call-template name="order-desc"/>
      <xsl:call-template name="order-to"/>
      <xsl:call-template name="paragraph">
        <xsl:with-param name="contents">
           <B>NB. Onderste strook van deze bestelbon meesturen bij de
levering<BR/>
           Bestelnummer op de factuur vermelden ! Voor
leveringsinstructies z.o.z.<BR/>
           <HR/></B>
        </xsl:with-param>
      </xsl:call-template>
      <xsl:call-template name="order-desc"/>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>

<xsl:template name="order-desc">
  <xsl:call-template name="paragraph">
    <xsl:with-param name="contents">
      <xsl:call-template name="text-line">
        <xsl:with-param name="contents" select="bib-info" />
      </xsl:call-template>
    </xsl:with-param>
  </xsl:call-template>
  <xsl:call-template name="labelled-rows">
    <xsl:with-param name="contents">
      <xsl:value-of select="concat('Bestelnummer:',
'==',z68-order-number,'##')"/>
      <xsl:value-of select="concat('Besteldatum:',
'==',z68-order-date,'####')"/>
      <xsl:value-of select="concat('Aantal:', '==',z68-no-units,'##')"/>
      <xsl:value-of select="concat('Uw referentie:',
'==',z68-vendor-code,'####')"/>
      <xsl:value-of select="concat('Prijs:', '==',z68-e-currency,'
',z68-unit-price,'##')"/>
      <xsl:value-of select="concat('Order Unit:',
'==',z68-ordering-unit,'####')"/>
    </xsl:with-param>
  </xsl:call-template>
  <xsl:call-template name="paragraph">
    <xsl:with-param name="contents">
      <xsl:value-of select="z68-vendor-note"/>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>

<xsl:template name="order-to">
  <xsl:call-template name="paragraph">
    <xsl:with-param name="contents">
      <B>Verzenden en berekenen aan:</B><BR/>
      <BR/>
      <table width="100%">
      <tr>
        <td width="45%">Universiteitsbibliotheek</td>
        <td width="20%" nowrap="yes">Telefoon boekbestellingen:</td>
        <td width="35%">071 - 527 ....</td>
      </tr>
      <tr>
        <td>Afd. Acquisitie</td>
        <td>Telefoon abonnementen:</td>
        <td>071 - 527 ....</td>
      </tr>
      <tr>
        <td>Postbus ...</td>
        <td>Fax:</td>
        <td>071 - 527 ....</td>
      </tr>
      <tr>
        <td>...</td>
        <td>Email:</td>
        <td>... at ...nl</td>
      </tr>
      <tr>
        <td>.... Leiden</td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td>Nederland</td>
        <td>BTWnr.:</td>
        <td>...</td>
      </tr>
      </table>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>

<xsl:template match="printout/*" priority="-1">
  <!-- catch all others, but don't display -->
</xsl:template>

<!-- functions -->

<xsl:template name="vendor-address">
  <xsl:if test="string-length(//z72-vendor-address-occ1) > 0">
    <xsl:value-of select="//z72-vendor-address-occ1"/><br/>
  </xsl:if>
  <xsl:if test="string-length(//z72-vendor-address-occ2) > 0">
    <xsl:value-of select="//z72-vendor-address-occ2"/><br/>
  </xsl:if>
  <xsl:if test="string-length(//z72-vendor-address-occ3) > 0">
    <xsl:value-of select="//z72-vendor-address-occ3"/><br/>
  </xsl:if>
  <xsl:if test="string-length(//z72-vendor-address-occ4) > 0">
    <xsl:value-of select="//z72-vendor-address-occ4"/><br/>
  </xsl:if>
  <xsl:if test="string-length(//z72-vendor-address-occ5) > 0">
    <xsl:value-of select="//z72-vendor-address-occ5"/><br/>
  </xsl:if>
  <xsl:if test="string-length(//z72-vendor-address-occ6) > 0">
    <xsl:value-of select="//z72-vendor-address-occ6"/><br/>
  </xsl:if>
  <xsl:if test="string-length(//z72-vendor-address-occ7) > 0">
    <xsl:value-of select="//z72-vendor-address-occ7"/><br/>
  </xsl:if>
</xsl:template>

<xsl:template name="body">
  <xsl:param name="contents">
     <xsl:apply-templates/>
  </xsl:param>
  <html>
    <body>
      <xsl:copy-of select="$contents" />
    </body>
  </html>
</xsl:template>

<xsl:template name="page">
  <xsl:param name="contents">
    <xsl:apply-templates/>
  </xsl:param>
  <div style="page-break-after: always">
    <xsl:copy-of select="$contents" />
  </div>
</xsl:template>

<xsl:template name="paragraph">
  <xsl:param name="contents">
    <xsl:apply-templates/>
  </xsl:param>
  <p>
    <xsl:copy-of select="$contents" />
  </p>
</xsl:template>

<xsl:template name="align-right">
  <xsl:param name="contents">
    <xsl:apply-templates/>
  </xsl:param>
  <table width="100%">
    <tr>
      <td width="50%"></td>
      <td width="50%" nowrap="yes">
        <xsl:copy-of select="$contents" />
      </td>
    </tr>
  </table>
</xsl:template>

<xsl:template name="text-line">
  <xsl:param name="contents"/>
  <xsl:choose>
    <xsl:when test="contains($contents, '##')">
      <xsl:value-of select="substring-before($contents,'##')"/>
      <br/>
      <xsl:call-template name="text-line">
        <xsl:with-param name="contents"
select="substring-after($contents,'##')"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
       <xsl:value-of select="$contents"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<xsl:template name="labelled-rows">
  <xsl:param name="contents"/>
  <table width="100%">
    <xsl:call-template name="labelled-cols">
      <xsl:with-param name="contents" select="$contents"/>
    </xsl:call-template>
  </table>
</xsl:template>

<xsl:template name="labelled-cols">
  <xsl:param name="contents"/>
    <xsl:choose>
      <xsl:when test="contains($contents, '####')">
        <tr>
          <xsl:call-template name="labelled-col">
            <xsl:with-param name="contents"
select="substring-before($contents, '####')"/>
          </xsl:call-template>
        </tr>
        <xsl:call-template name="labelled-cols">
          <xsl:with-param name="contents"
select="substring-after($contents, '####')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <tr>
          <xsl:call-template name="labelled-col">
            <xsl:with-param name="contents" select="$contents"/>
          </xsl:call-template>
        </tr>
      </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="labelled-col">
  <xsl:param name="contents"/>
  <xsl:choose>
    <xsl:when test="contains($contents, '##')">
      <xsl:call-template name="label-value">
        <xsl:with-param name="contents"
select="substring-before($contents, '##')"/>
      </xsl:call-template>
      <xsl:call-template name="labelled-col">
        <xsl:with-param name="contents"
select="substring-after($contents, '##')"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="label-value">
        <xsl:with-param name="contents" select="$contents"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template name="label-value">
  <xsl:param name="contents"/>
  <td width="20%">
    <b>
      <xsl:value-of select="substring-before($contents, '==')"/>
    </b>
  </td>
  <td width="30%">
    <xsl:value-of select="substring-after($contents, '==')"/>
  </td>
</xsl:template>

</xsl:transform>


greetings,
Lucas

-----Original Message-----
From: Wendell Piez [mailto:wapiez@xxxxxxxxxxxxxxxx]
Sent: vrijdag 18 maart 2005 17:32
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: [SPAM-BA] - Re: [xsl] decorator / wrapper design pattern -
Bayesian Filter detected spam

Hi Lucas,

I'm not sure whether this could rightly be said to map to the
"decorator"
pattern (maybe so), but it seems to me you may be looking for the idiom:

<xsl:template match="something">
   <xsl:call-template name="some-wrapper"/> </xsl:template>

<xsl:template name="some-wrapper">
   <xsl:param name="contents">
     <xsl:apply-templates/>
   </xsl:param>
   <wrapper>
     <xsl:copy-of select="$contents"/>
   </wrapper>
</xsl:template>

this allows you also to do things like

<xsl:template match="something-else">
   <xsl:call-template name="some-wrapper">
     <xsl:with-param select="contents">
       <xsl:call-template name="some-other-wrapper"/>
     </xsl:with-param>
   </xsl:call-template>
</xsl:template>

or even

<xsl:template match="another-something-else">
   <xsl:call-template name="some-wrapper">
     <xsl:with-param select="contents">
       <xsl:text>Wrap me!</xsl:text>
     </xsl:with-param>
   </xsl:call-template>
   <xsl:apply-templates/>
</xsl:template>

That is, the "wrapper" (or decorator) template can wrap anything you
pass it.

A "thick" solution to a nasty problem (map a set of attributes to a set
of
wrappers) using this idiom (although by matching templates, not calling
them by name) appears at

But I should also caution you that it isn't very common to have to do
this; lighter-weight solutions are usually possible. Also, as Jay says,
the requirements this addresses are often better answered by pushing the
problem into the next layer up, for example into a CSS stylesheet to be
applied to HTML output.

Enjoy!
Wendell


At 08:37 AM 3/18/2005, you wrote:
>Hi,
>
>I'm using XSL version 1.0 and am trying to use the decorator design
>pattern, but can't get it to work in XSL.
>Here is what I try to achieve:
>Different types of elements all need to be surrounded by the same text.
>For example:
>
>I've XML:
><base>
>   <section>
>      <title>the title</title>
>      <paragraph>some text</paragraph>
>      <paragraph>more text</paragraph>
>   </section>
>   <section>
>      <title>the title</title>
>      <paragraph>other text</paragraph>
>      <paragraph>more other text</paragraph>
>      <paragraph>and more text</paragraph>
>   </section>
></base>
>
>Now I want all text in titles and in paragraphs to be italic and in
>titles also to be bold.
>My first thought was to use call-template like this:
><xsl:template match="title">
>   <xsl:call-template name="bold">
>     <xsl:call-template name="italic">
>        <xsl:value-of select="."/>
>     </xsl:call-template>
>   </xsl:call-template>
></xsl:template>
>
>But this is not the way to do this.
>I cannot however figure out or find the solution. The decoration that
>must be applied is much more complicated than bold or italic, but that
>is besides the point, I think.
>Here is my second try, but here is the problem that I cannot nest
>decorators, so bold and italic is not possible on the same element:
>
><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>version="1.0">
>
><xsl:template match="/">
>   <xsl:call-template name="body"/>
></xsl:template>
>
><xsl:template match="section">
>   <xsl:apply-templates />
>   <br/>
></xsl:template>
>
><xsl:template match="title">
>   <xsl:call-template name="bold" />
>   <br/>
></xsl:template>
>
><xsl:template match="paragraph">
>   <xsl:call-template name="italic" />
></xsl:template>
>
><xsl:template name="bold">
>   <b>
>      <xsl:apply-templates/>
>   </b>
></xsl:template>
>
><xsl:template name="italic">
>   <i>
>      <xsl:apply-templates/>
>   </i>
></xsl:template>
>
><xsl:template name="body">
>   <html>
>     <body>
>       <xsl:apply-templates />
>     </body>
>   </html>
></xsl:template>
>
></xsl:stylesheet>
>
>
>Can anybody give me a pointer?
>
>Thanks in advance
>
>Lucas


======================================================================
Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
   Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================

Current Thread