在元素中包装模板输出

Wrap Template Output in Elements

我需要在许多模板的输出周围添加一个包装器。下面的示例显示了我正在尝试做的事情。

我当前的模板直接调用 outputText、outputTable 模板。

现在,我需要将每个模板的输出包装在几个 div 中。这在我的 XSL 中发生了很多(很多!)次,所以我正在寻找一种不需要在每次调用之前和之后添加包装器模板的解决方案。

我试过在 xsl:call 模板中添加 xsl:call 模板。我也试过将模板名称作为参数传递(下面的示例)。

有什么方法可以在每次调用模板之前和之后添加代码,而无需在所有地方复制包装代码?

示例 XSL

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

<xsl:template match='/' >
<html>
    <body>
    <div class='content'>
        <div class='row'>
            <div class='col-sm-6'>
                <!-- 
                    Original Call straight to the template 
                    <xsl:call-template name='outputText'>
                -->
                <xsl:call-template name='wrapper'>
                    <xsl:with-param name='outputText'/>
                </xsl:call-template>
            </div>

            <div class='col-sm-6'>
                <!-- 
                    Original Call straight to the template 
                    <xsl:call-template name='outputTable'>
                -->
                <xsl:call-template name='wrapper'>
                    <xsl:with-param name='outputTable'/>
                </xsl:call-template>
            </div>
        </div>
    </div>
    </body>
</html>
</xsl:template>

<xsl:template name='wrapper'>
    <xsl:param name='template'/>
    <div class='top-wrapper'>
        <div class='wrappercontent'>
            <h1>Content Wrapper</h1>
        </div>
        <div class='inner-wrapper'>
            <xsl:call-template name='{$template}'/>
        </div>
    </div>
</xsl:template>

<xsl:template name='outputText'>
    <h1>Test Header</h1>
    <p>Test content</p>
</xsl:template>

<xsl:template name='outputTable'>
    <h1>Test Table</h1>
    <table>
        <tr>
            <th>Name</th>
            <th>Age</th>
        </tr>
        <xsl:for-each select='/xml/character'>
            <tr>
                <td><xsl:value-of select='@name'/></td>
                <td><xsl:value-of select='@age'/></td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>
</xsl:stylesheet>

样本XML

<xml>
    <character name='Zaphod Beeblerox' age='100'/>
    <character name='Harry Potter' age='13'/>
</xml>

所需的输出如下所示

<html>
    <body>
        <div class="content">
            <div class="row">
                <div class="col-sm-6">
                    <div class="top-wrapper">
                        <div class="wrappercontent">
                            <h1>Content Wrapper</h1>
                        </div>
                        <div class="inner-wrapper">
                            <h1>Test Header</h1>
                            <p>Test content</p>
                        </div>
                    </div>
                </div>
                <div class="col-sm-6">
                    <div class="top-wrapper">
                        <div class="wrappercontent">
                            <h1>Content Wrapper</h1>
                        </div>
                        <div class="inner-wrapper">
                            <h1>Test Table</h1>
                            <table>
                                <tr>
                                    <th>Name</th>
                                    <th>Age</th>
                                </tr>
                                <tr>
                                    <td>Zaphod Beeblerox</td>
                                    <td>100</td>
                                </tr>
                                <tr>
                                    <td>Harry Potter</td>
                                    <td>13</td>
                                </tr>
                            </table>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

您可以使用微流水线,例如...

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="1.0">
<xsl:output method="html" indent="yes" encoding="utf-8" version="5" doctype-system="" />
<xsl:strip-space elements="*"/>

<xsl:template match="/">
  <hmtl>
    <head>
      <title>Hitchhiker's guide</title>
    </head>
    <body>
      <xsl:apply-templates select="xml" />
    </body>
  </hmtl>
</xsl:template>

<xsl:template match="xml">
  <div class='content'>
    <div class='row'>
      <div class='col-sm-6'>
        <xsl:variable name="content-to-be-wrapped">
          <xsl:call-template name="outputText" />
        </xsl:variable>
        <xsl:call-template name="Wrap">
          <xsl:with-param name="content" select="$content-to-be-wrapped" />
        </xsl:call-template>
      </div>

      <div class='col-sm-6'>
        <xsl:variable name="content-to-be-wrapped">
          <xsl:call-template name="outputTable" />
        </xsl:variable>
        <xsl:call-template name="Wrap">
          <xsl:with-param name="content" select="$content-to-be-wrapped" />
        </xsl:call-template>
      </div>
    </div>
  </div>
</xsl:template>

<xsl:template name="Wrap">
  <xsl:param name="content" />
  <div class='top-wrapper'>
    <div class='wrappercontent'><h1>Content Wrapper</h1></div>
    <div class='inner-wrapper'>
      <xsl:copy-of select="$content" />
    </div>
  </div>  
</xsl:template>

<xsl:template name="outputText">
  <h1>Test Header</h1>
  <p>Test content</p>
</xsl:template>

<xsl:template name="outputTable">
  <h1>Test Table</h1>
  <table>
    <tr><th>Name</th><th>Age</th></tr>
    <xsl:apply-templates select="character" />
  </table>
</xsl:template>  

<xsl:template match="character">
  <tr>
    <td><xsl:value-of select='@name'/></td>
    <td><xsl:value-of select='@age'/></td>
  </tr>
</xsl:template>  

</xsl:stylesheet>

...或直接...

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="1.0">
<xsl:output method="html" indent="yes" encoding="utf-8" version="5" doctype-system="" />
<xsl:strip-space elements="*"/>

<xsl:template match="/">
  <hmtl>
    <head>
      <title>Hitchhiker's guide</title>
    </head>
    <body>
      <xsl:apply-templates select="xml" />
    </body>
  </hmtl>
</xsl:template>

<xsl:template match="xml">
  <div class='content'>
    <div class='row'>
      <div class='col-sm-6'>
        <xsl:call-template name="Wrap">
          <xsl:with-param name="content">
            <xsl:call-template name="outputText" />
          </xsl:with-param>
        </xsl:call-template>
      </div>

      <div class='col-sm-6'>
        <xsl:call-template name="Wrap">
          <xsl:with-param name="content">
            <xsl:call-template name="outputTable" />
          </xsl:with-param>
        </xsl:call-template>
      </div>
    </div>
  </div>
</xsl:template>

<xsl:template name="Wrap">
  <xsl:param name="content" />
  <div class='top-wrapper'>
    <div class='wrappercontent'><h1>Content Wrapper</h1></div>
    <div class='inner-wrapper'>
      <xsl:copy-of select="$content" />
    </div>
  </div>  
</xsl:template>

<xsl:template name="outputText">
  <h1>Test Header</h1>
  <p>Test content</p>
</xsl:template>

<xsl:template name="outputTable">
  <h1>Test Table</h1>
  <table>
    <tr><th>Name</th><th>Age</th></tr>
    <xsl:apply-templates select="character" />
  </table>
</xsl:template>  

<xsl:template match="character">
  <tr>
    <td><xsl:value-of select='@name'/></td>
    <td><xsl:value-of select='@age'/></td>
  </tr>
</xsl:template>  

</xsl:stylesheet>

上述 XSLT 1.0 样式表,当应用于输入时...

<xml>
    <character name='Zaphod Beeblerox' age='100'/>
    <character name='Harry Potter' age='13'/>
</xml>

... 产量输出 html 页 ...

<!DOCTYPE html SYSTEM "">
<hmtl>
  <head>
    <META http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Hitchhiker's guide</title>
  </head>
  <body>
    <div class="content">
      <div class="row">
        <div class="col-sm-6">
          <div class="top-wrapper">
            <div class="wrappercontent">
              <h1>Content Wrapper</h1>
            </div>
            <div class="inner-wrapper">
              <h1>Test Header</h1>
              <p>Test content</p>
            </div>
          </div>
        </div>
        <div class="col-sm-6">
          <div class="top-wrapper">
            <div class="wrappercontent">
              <h1>Content Wrapper</h1>
            </div>
            <div class="inner-wrapper">
              <h1>Test Table</h1>
              <table>
                <tr>
                  <th>Name</th>
                  <th>Age</th>
                </tr>
                <tr>
                  <td>Zaphod Beeblerox</td>
                  <td>100</td>
                </tr>
                <tr>
                  <td>Harry Potter</td>
                  <td>13</td>
                </tr>
              </table>
            </div>
          </div>
        </div>
      </div>
    </div>
  </body>
</hmtl>