XML/XSLT stylesheet/call template

Материал из Web эксперт
Перейти к: навигация, поиск

Call template twice

File: Data.xml
<chapter>
  <title>Chapter 1</title>
  <para>para1</para>
  <para author="ar">para2</para>
  <section>
    <title>Chapter 1, Section 1</title>
    <para>para3</para>
    <para>line 1</para>
  </section>
</chapter>
File: Transform.xslt
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">
  <xsl:template name="titles">
    <xsl:param name="headerElement">h4</xsl:param>
    <xsl:element name="{$headerElement}">
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>
  <xsl:template match="chapter/title">
    <xsl:call-template name="titles">
      <xsl:with-param name="headerElement">h1</xsl:with-param>
    </xsl:call-template>
  </xsl:template>
  <xsl:template match="section/title">
    <xsl:call-template name="titles">
      <xsl:with-param name="headerElement" select=""h2"" />
    </xsl:call-template>
  </xsl:template>
  <xsl:template match="para">
    <p>
      <xsl:apply-templates />
    </p>
  </xsl:template>
  <xsl:template match="chapter">
    <html>
      <body>
        <xsl:apply-templates />
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
Output:
<html>
   <body>
        
      <h1>Chapter 1</h1>
        
      <p>para1</p>
        
      <p>para2</p>
        
          
      <h2>Chapter 1, Section 1</h2>
          
      <p>para3</p>
          
      <p>line 1</p>
        
      
   </body>
</html>



call-template with parameter

File: Data.xml

<?xml version="1.0"?>
<SCENE>
  <TITLE>title</TITLE>
  <STAGEDIR>A</STAGEDIR>
  <SPEECH>
    <SPEAKER>C</SPEAKER>
    <LINE>B</LINE>
    <LINE>C</LINE>
    <LINE>D</LINE>
  </SPEECH>
</SCENE>
File: Transform.xslt
<?xml version="1.0"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs" version="2.0">
  <xsl:template name="longest-speech" as="element(SPEECH)?">
    <xsl:param name="list" as="element(SPEECH)*" />
    <xsl:choose>
      <xsl:when test="$list">
        <xsl:variable name="first" select="count($list[1]/LINE)"
          as="xs:integer" />
        <xsl:variable name="longest-of-rest"
          as="element(SPEECH)?">
          <xsl:call-template name="longest-speech">
            <xsl:with-param name="list"
              select="$list[position()!=1]" />
          </xsl:call-template>
        </xsl:variable>
        <xsl:choose>
          <xsl:when
            test="$first gt count($longest-of-rest/LINE)">
            <xsl:sequence select="$list[1]" />
          </xsl:when>
          <xsl:otherwise>
            <xsl:sequence select="$longest-of-rest" />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
    </xsl:choose>
  </xsl:template>
  <xsl:template match="/">
    <longest-speech>
      <xsl:call-template name="longest-speech">
        <xsl:with-param name="list" select="//SPEECH" />
      </xsl:call-template>
    </longest-speech>
  </xsl:template>
</xsl:transform>

Output:
<?xml version="1.0" encoding="UTF-8"?><longest-speech><SPEECH>
    <SPEAKER>C</SPEAKER>
    <LINE>B</LINE>
    <LINE>C</LINE>
    <LINE>D</LINE>
  </SPEECH></longest-speech>



Call template with parameters

File: Data.xml
<winelist>
  <wine grape="Chardonnay">
    <winery>shop 2</winery>
  </wine>
  <wine grape="Cabernet">
    <winery>shop 1</winery>
  </wine>
</winelist>

File: Transform.xslt
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">
  <xsl:output method="xml" omit-xml-declaration="yes" />
  <xsl:template name="globalReplace">
    <xsl:param name="outputString" />
    <xsl:param name="target" />
    <xsl:param name="replacement" />
    <xsl:choose>
      <xsl:when test="contains($outputString,$target)">
        <xsl:value-of
          select="concat(substring-before($outputString,$target),$replacement)" />
        <xsl:call-template name="globalReplace">
          <xsl:with-param name="outputString" select="substring-after($outputString,$target)" />
          <xsl:with-param name="target" select="$target" />
          <xsl:with-param name="replacement" select="$replacement" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$outputString" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template match="text()">
    <xsl:call-template name="globalReplace">
      <xsl:with-param name="outputString" select="." />
      <xsl:with-param name="target" select=""finish"" />
      <xsl:with-param name="replacement" select=""FINISH"" />
    </xsl:call-template>
  </xsl:template>
  <xsl:template match="@*|*">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
Output:
<winelist>
  <wine grape="Chardonnay">
    <winery>shop 2</winery>
  </wine>
  <wine grape="Cabernet">
    <winery>shop 1</winery>
  </wine>
</winelist>



One template calls another template

File: Data.xml
<wine grape="Cabernet">
  <winery>shop 1</winery>
  <product>product 1</product>
  <year>1996</year>
  <price>11.99</price>
</wine>
File: Transform.xslt
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">
  <xsl:output method="xml" omit-xml-declaration="yes" indent="no" />
  <xsl:template name="boldIt">
    <b>
      <xsl:apply-templates />
    </b>
  </xsl:template>
  <xsl:template match="winery">
    <p>
      <xsl:call-template name="boldIt" />
    </p>
  </xsl:template>
  <xsl:template match="product">
    <p>
      <xsl:call-template name="boldIt" />
    </p>
  </xsl:template>
  <xsl:template match="year | price">
    <p>
      <xsl:apply-templates />
    </p>
  </xsl:template>
  
</xsl:stylesheet>
Output:

  <p><b>shop 1</b></p>
  <p><b>product 1</b></p>
  <p>1996</p>
  <p>11.99</p>



template that does the replacement

File: Data.xml
<winelist>
  <wine grape="Chardonnay">
    <winery>shop 2</winery>
  </wine>
  <wine grape="Cabernet">
    <winery>shop 1</winery>
  </wine>
</winelist>
File: Transform.xslt
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">
  <xsl:output method="xml" indent="no" />
  <xsl:template name="globalReplace">
    <xsl:param name="outputString" />
    <xsl:param name="target" />
    <xsl:param name="replacement" />
    <xsl:choose>
      <xsl:when test="contains($outputString,$target)">
        <xsl:value-of
          select="concat(substring-before($outputString,$target),$replacement)" />
        <xsl:call-template name="globalReplace">
          <xsl:with-param name="outputString"
            select="substring-after($outputString,$target)" />
          <xsl:with-param name="target" select="$target" />
          <xsl:with-param name="replacement"
            select="$replacement" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$outputString" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template match="year/text()">
    <xsl:call-template name="globalReplace">
      <xsl:with-param name="outputString" select="." />
      <xsl:with-param name="target" select=""9"" />
      <xsl:with-param name="replacement" select=""0"" />
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="UTF-8"?><winelist>
  <wine grape="Chardonnay">
    <winery>shop 2</winery>
  </wine>
  <wine grape="Cabernet">
    <winery>shop 1</winery>
  </wine>
</winelist>