How can these XSLT documents be DRY-ed

2020-02-11 16:42发布

问题:

I have made two pages and now I wonder if I can DRY them.

Here the XSLT:

Frontpage: http://pastebin.com/yuZL913W dagboek-page: http://pastebin.com/6FGYvpvf (Edited)

Roelof

Sorry one of the links is wrong. I edited this.

My question is how to DRY these so I can reuse parts. Only the <div id="posts"> is different. I think I understand the fill in the blanks but it is one big xslt file. Is this possible without named templates and call-templates

回答1:

Here is one way -- what I call "Fill-in-the-blanks" to separate content from processing and to parameterize processing:

Rendering file (c:/temp/delete/nc3.xml):

<html  xmlns:gen="gen:gen">
<gen:data from="params" mode="top"/>
<body >
             <div id="outer">
                 <div id="container">
                     <div id="search">
                         <form method="get" id="searchform" action="http://www.notepadchaos.com/">
                             <input type="text" value="" name="s" id="s" class="txtField" />
                             <input type="submit" id="searchsubmit" class="btnSearch" value="Find It " />
                        </form>
                     </div>
                         <div id="title">
                             <h2>Tamara Wobben</h2>
                        </div>
                     </div>
                     <div id="content">
                        <div class="col01">
                                <div class="post">
                                     <h3> <gen:data from="entry/title"/> </h3>
                                    <div class="post-inner">
                             <gen:data from="section/entry/tekst" />
                               </div></div></div>
                              <div class="side-columns">
                             <div class="col02">
                                 <div class="pages">
                                     <!-- hier komen de losse pagina's -->
                                 </div>
                                 <div class="pages-bottom"></div>
                                 <div class="categories-upper"></div>
                                 <div class="categories">
                                    <!-- hier komt het menu  -->
                                </div>
                                 <div class="categories-btm"></div>
                                </div>
                             <div class ="col03">
                                <div class="recent-post" >
                                <!-- hier komen de recente posts -->
                                </div>
                                <div class="postit-bottom"></div>
                            </div>
                         </div>
<br style="clear:both" />
                     </div>
                     <gen:data from="params" mode="down"/>
                </div>
            </body>
</html>

Data file (c:/temp/delete/data.xml):

<data>
    <params>
    <today>2011-12-29</today>
    <current-time>22:17</current-time>
    <this-year>2011</this-year>
    <this-month>12</this-month>
    <this-day>29</this-day>
    <timezone>+01:00</timezone>
    <website-name>Tamara Wobben</website-name>
    <page-title>frontpage</page-title>
    <root>http://test.tamarawobben.nl</root>
    <workspace>http://test.tamarawobben.nl/workspace</workspace>
    <root-page>frontpage</root-page>
    <current-page>frontpage</current-page>
    <current-page-id>6</current-page-id>
    <current-path>/?debug=xml</current-path>
    <parent-path>/</parent-path>
    <current-url>http://test.tamarawobben.nl/?debug=xml</current-url>
    <upload-limit>2097152</upload-limit>
    <symphony-version>2.2.5</symphony-version>
    <cookie-username>xxxx</cookie-username>
    <cookie-pass>xxxxx</cookie-pass>
    <site-mode>live</site-mode>
</params>
    <events />
          <image>
              <section id="7" handle="images">Images</section>
              <entry id="13">
                 <image size="22 KB" path="/images" type="image/jpeg">
                    <filename>img_5874.jpg</filename>
                    <meta creation="2011-12-19T18:40:04+01:00" width="400" height="267" />
                 </image>
             </entry>
         </image>
         <recent-posts>
              <section id="9" handle="dagboek">Dagboek</section>
                   <entry id="15">
                         <datum time="00:00" weekday="2">2005-02-22</datum>
                         <titel handle="7-weken-echo">7 weken echo</titel>
                   </entry>
         </recent-posts>
<section>
      <section id="6" handle="sections">Sections</section>
          <entry id="12">
               <title handle="even-voorstellen">Even Voorstellen</title>
               <tekst><p>FLOAT : img_5874.jpg</p> 55 56<p>Naam : Tamara Wobben<br /> 57Geboorte gewicht : 2000 gram<br /> 58Geboorte lengte : 44 cm.<br /> 59Geboortedatum : 1 september 2005  </p>
                 </tekst>
            </entry>
    </section>
</data>

XSLT code:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:gen="gen:gen" exclude-result-prefixes="gen">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pFormPath" select=
     "'file:///c:/temp/delete/nc3.xml'"/>
 <xsl:param name="pDataPath" select=
     "'file:///c:/temp/delete/data.xml'"/>

 <xsl:variable name="vFormDoc" select="document($pFormPath)"/>
 <xsl:variable name="vDataDoc" select="document($pDataPath)"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/">
  <xsl:apply-templates select="$vFormDoc/*"/>
 </xsl:template>

 <xsl:template match=
 "gen:data
    [@from='params'
    and
     @mode='top'
    ]">

  <!-- Use $vDataDoc to populate this -->

  T O P   S T U F
 </xsl:template>

 <xsl:template match=
 "gen:data[@from='entry/Title']">

  <!-- Use $vDataDoc to populate this -->

  E N T R Y   T I T L E
 </xsl:template>
 <xsl:template match=
 "gen:data[@from='section/entry/tekst']">

  <!-- Use $vDataDoc to populate this -->

   S E C T I O N   E N T R Y   T E X T
 </xsl:template>

 <xsl:template match=
 "gen:data
    [@from='params'
    and
     @mode='down'
    ]">

  <!-- Use $vDataDoc to populate this -->

  D O W N   S T U F
 </xsl:template>

</xsl:stylesheet>

Source XML file (not used):

<t/>

When the above transformation is performed on any XML file (not used), the rendering file is populated with data from the data file. The templates that process the placeholder gen:data elements, are dummy but still demonstrate how this processing works.

The result of the processing:

<html xmlns:gen="gen:gen">



   T O P   S T U F

   <body>
      <div id="outer">
         <div id="container">
            <div id="search">
               <form method="get" id="searchform" action="http://www.notepadchaos.com/"><input type="text" value="" name="s" id="s" class="txtField"><input type="submit" id="searchsubmit" class="btnSearch" value="Find It "></form>
            </div>
            <div id="title">
               <h2>Tamara Wobben</h2>
            </div>
         </div>
         <div id="content">
            <div class="col01">
               <div class="post">
                  <h3>
                     <gen:data from="entry/title"></gen:data>
                  </h3>
                  <div class="post-inner">



                     S E C T I O N   E N T R Y   T E X T

                  </div>
               </div>
            </div>
            <div class="side-columns">
               <div class="col02">
                  <div class="pages">
                     <!-- hier komen de losse pagina's -->
                  </div>
                  <div class="pages-bottom"></div>
                  <div class="categories-upper"></div>
                  <div class="categories">
                     <!-- hier komt het menu  -->
                  </div>
                  <div class="categories-btm"></div>
               </div>
               <div class="col03">
                  <div class="recent-post">
                     <!-- hier komen de recente posts -->
                  </div>
                  <div class="postit-bottom"></div>
               </div>
            </div><br style="clear:both"></div>



         D O W N   S T U F

      </div>
   </body>
</html>

Do note:

  1. This code can populate any rendering document (path passed as an external parameter) using the data from any data document (again path passed as an external parameter). Thus it becomes possible to create different outputs/formats populated with different data.

  2. The placeholders (gen:data elements) to be replaced with "live content" can have different format and semantics -- no limits to one's imagination.

  3. Editors (non-XSLT experts) can work on one or more rendering documents independently from each other and from the XSLT developers.

  4. A higher degree of reusability, flexibility and maintainability is achieved.



标签: xslt dry