XML Tutorial/XSLT stylesheet/variable

Материал из Web эксперт
Версия от 18:22, 25 мая 2010; (обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Define and use variable

File: Data.xml
<?xml version="1.0"?>
<addressbook>
  <address>
    <name>
      <title>Ms.</title>
      <first-name>Jack</first-name>
      <last-name>Smith</last-name>
    </name>
    <street>707 Main Way</street>
    <city>New York</city>
    <state>ME</state>
    <zip>00218</zip>
  </address>
</addressbook>

File: Transform.xslt
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="no" />
  <xsl:strip-space elements="*" />
  <xsl:variable name="newline">
    <xsl:text></xsl:text>
  </xsl:variable>
  <xsl:template match="/">
    <xsl:for-each select="addressbook/address">
      <xsl:sort select="name/last-name" />
      <xsl:value-of select="name/title" />
      <xsl:text> </xsl:text>
      <xsl:value-of select="name/first-name" />
      <xsl:text> </xsl:text>
      <xsl:value-of select="name/last-name" />
      <xsl:value-of select="$newline" />
      <xsl:value-of select="street" />
      <xsl:value-of select="$newline" />
      <xsl:value-of select="city" />
      <xsl:text>, </xsl:text>
      <xsl:value-of select="state" />
      <xsl:text>  </xsl:text>
      <xsl:value-of select="zip" />
      <xsl:value-of select="$newline" />
      <xsl:value-of select="$newline" />
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
Output:
Ms. Jack Smith707 Main WayNew York, ME  00218


Define variable and use it

File: Data.xml

<x>
   <input>7</input>
   <input>27</input>
</x>
File: Transform.xslt
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">
  <xsl:output method="text" indent="yes" version="1.0" />
  <xsl:template match="x">
    <xsl:apply-templates select="y" />
  </xsl:template>
  <xsl:template match="y">
    <xsl:param name="x" select="/x/input" />
    <xsl:variable name="y" select="$x - 1" />
    <xsl:variable name="z" select="." />
    <xsl:value-of select="$x" />
    <xsl:text> - 1 = </xsl:text>
    <xsl:value-of select="$y" />
    <xsl:text>&#013;</xsl:text>
    <xsl:if test="$x > 1">
      <xsl:apply-templates select="$z">
        <xsl:with-param name="x" select="$x - 1" />
      </xsl:apply-templates>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>


demonstrate different ways of setting xsl:variable

File: Data.xml
<?xml version="1.0" encoding="utf-8"?>
<data>
  <chapter>Chapter A</chapter>
  <chapter>Chapter B</chapter>
  <chapter>Chapter C</chapter>
  <chapter>Chapter D</chapter>
</data>
File: Transform.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="totalChapters" select="count(//chapter)"/>
    <xsl:template match="/">
      <TABLE>
        <xsl:for-each select="//chapter">
          <TR>
            <TD>
              <xsl:value-of select="."/>
              <xsl:text> (</xsl:text>
              <xsl:value-of select="position()"/>
              <xsl:text>/</xsl:text>
              <xsl:value-of select="$totalChapters"/>
              <xsl:text>)</xsl:text>
            </TD>
          </TR>
        </xsl:for-each>
      </TABLE>
    </xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="UTF-8"?><TABLE><TR><TD>Chapter A (1/4)</TD></TR><TR><TD>Chapter B (2/4)</TD></TR><TR><TD>Chapter C (3/4)</TD></TR><TR><TD>Chapter D (4/4)</TD></TR></TABLE>


Fill position to a variable

File: Data.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="Transform.xslt" ?>
<nodeTester type="referral">
  <function>
    <name>position() function</name>
  </function>
  <text>
    This function helps find the position of a node in the node
    list.
  </text>
</nodeTester>
File: Transform.xslt
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="no" />
  <xsl:template match="nodeTester">
    <xsl:apply-templates />
  </xsl:template>
  <xsl:template match="text">
    <xsl:variable name="myPositionVariable" select="position()" />
    NodeList position =
    <xsl:value-of select="$myPositionVariable" />
  </xsl:template>
</xsl:stylesheet>
Output:

  
    position() function
  
  
    NodeList position =
    4


if a variable has some defined value

File: Data.xml
<?xml version="1.0" encoding="utf-8"?>
<data>
  <animal>cat</animal>
  <animal>dog</animal>
  <animal>cow</animal>
</data>
File: Transform.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="color">red</xsl:variable>
    <xsl:template match="//animal">
      <xsl:choose>
        <xsl:when test="boolean($color)">
          <P style="color:{$color}">
            <xsl:value-of select="."/>
          </P>
        </xsl:when>
        <xsl:otherwise>
          <paragraph>
            <xsl:value-of select="."/>
          </P>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="UTF-8"?>
  <P style="color:red">cat</P>
  <P style="color:red">dog</P>
  <P style="color:red">cow</P>


There is an important difference in variable value specification.

File: Data.xml
<?xml version="1.0" encoding="utf-8"?>
<data>
    <AAA>
      <BBB>
        <CCC>C1</CCC>
      </BBB>
      <CCC>C2</CCC>
      <CCC>C3</CCC>
    </AAA>
    <AAA>
      <CCC>
        <DDD>D1</DDD>
        <DDD>D2</DDD>
      </CCC>
    </AAA>
</data>
File: Transform.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="var1" select="//AAA/CCC/text()"/>
    <xsl:variable name="var2">//AAA/CCC/text()</xsl:variable>
    <xsl:template match="/">
      <xsl:call-template name="function">
        <xsl:with-param name="path1" select="//AAA/CCC/DDD"/>
        <xsl:with-param name="path2">//AAA/CCC/DDD</xsl:with-param>
      </xsl:call-template>
    </xsl:template>
    <xsl:template name="function">
      <xsl:param name="path1"/>
      <xsl:param name="path2"/>
      <paragraph>
        <xsl:value-of select="$path2"/>
        <xsl:text> : </xsl:text>
        <xsl:value-of select="$path1"/>
      </P>
      <paragraph>
        <xsl:value-of select="$var2"/>
        <xsl:text> : </xsl:text>
        <xsl:for-each select="$var1">
          <xsl:value-of select="."/>
          <xsl:text/>
        </xsl:for-each>
      </P>
    </xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="UTF-8"?><paragraph>//AAA/CCC/DDD : D1</P><paragraph>//AAA/CCC/text() : C2C3
        
        
      </P>


Use variable to hold a result tree

File: Data.xml
<?xml version="1.0" encoding="utf-8"?>
<data>    
        <TABLE border="1">
      <TR>
        <TD>AAA</TD>
        <TD>BBB</TD>
      </TR>
      <TR>
        <TD>aaa</TD>
        <TD>bbb</TD>
      </TR>
    </TABLE>
    <TABLE border="1">
      <TR>
        <TD>1111111</TD>
      </TR>
      <TR>
        <TD>22222222</TD>
      </TR>
      </TABLE>
</data>
File: Transform.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="A1">
      <xsl:copy-of select="//TABLE[1]"/>
    </xsl:variable>
    <xsl:variable name="A2">
      <xsl:copy-of select="//TABLE[2]"/>
    </xsl:variable>
    <xsl:template match="/">
      <xsl:copy-of select="$A2"/>
      <xsl:copy-of select="$A1"/>
      <xsl:copy-of select="$A2"/>
    </xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="UTF-8"?><TABLE border="1">
      <TR>
        <TD>1111111</TD>
      </TR>
      <TR>
        <TD>22222222</TD>
      </TR>
      </TABLE><TABLE border="1">
      <TR>
        <TD>AAA</TD>
        <TD>BBB</TD>
      </TR>
      <TR>
        <TD>aaa</TD>
        <TD>bbb</TD>
      </TR>
    </TABLE><TABLE border="1">
      <TR>
        <TD>1111111</TD>
      </TR>
      <TR>
        <TD>22222222</TD>
      </TR>
      </TABLE>


Variable assignment with choose statement

File: Data.xml
<?xml version="1.0"?>
<list xml:lang="en">
  <title>title 1</title>
  <listitem>item 1</listitem>
  <listitem>item 2</listitem>
  <listitem>item 3</listitem>
  <listitem xml:lang="sw">item 4</listitem>
  <listitem xml:lang="en-gb">item 5</listitem>
  <listitem xml:lang="zu">item 6</listitem>
  <listitem xml:lang="jz">item 7</listitem>
</list>

File: Transform.xslt
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:variable name="favoriteNumber" select="23"/>
  <xsl:variable name="favoriteColor" select=""blue""/>
  <xsl:variable name="complicatedVariable">
    <xsl:choose>
      <xsl:when test="count(//listitem) &gt; 10">
        <xsl:text>really long list</xsl:text>
      </xsl:when>
      <xsl:when test="count(//listitem) &gt; 5">
        <xsl:text>moderately long list</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>fairly short list</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:template match="/">
    <xsl:text>Hello!  Your favorite number is </xsl:text>
    <xsl:value-of select="$favoriteNumber"/>
    <xsl:text>.&#xA;Your favorite color is </xsl:text>
    <xsl:value-of select="$favoriteColor"/>
    <xsl:text>.&#xA;&#xA;Here is a </xsl:text>
    <xsl:value-of select="$complicatedVariable"/>
    <xsl:text>:&#xA;</xsl:text>
    <xsl:variable name="listitems" select="list/listitem"/>
    <xsl:call-template name="processListitems">
      <xsl:with-param name="items" select="$listitems"/>
    </xsl:call-template>
  </xsl:template>
  <xsl:template name="processListitems">
    <xsl:param name="items"/>
    <xsl:variable name="favoriteColor">
      <xsl:text>chartreuse</xsl:text>
    </xsl:variable>
    
    <xsl:text>    (Your favorite color is now </xsl:text>
    <xsl:value-of select="$favoriteColor"/>
    <xsl:text>.)&#xA;</xsl:text>
    <xsl:for-each select="$items">
      <xsl:value-of select="position()"/>
      <xsl:text>.  </xsl:text>
      <xsl:value-of select="."/>
      <xsl:text>&#xA;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
Output:
Hello!  Your favorite number is 23.
Your favorite color is blue.
Here is a moderately long list:
    (Your favorite color is now chartreuse.)
1.  item 1
2.  item 2
3.  item 3
4.  item 4
5.  item 5
6.  item 6
7.  item 7


Variable scope

File: Data.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- testlines.xml -->
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>
File: Transform.xslt
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:template match="/">
    <xsl:apply-templates select="ul/li"/>
  </xsl:template>
  <xsl:template match="li">
    <xsl:variable name="single-quote">
      <xsl:text>&apos;</xsl:text>
    </xsl:variable>
    <xsl:variable name="two-quotes">
      <xsl:text>&apos;&apos;</xsl:text>
    </xsl:variable>
    <xsl:variable name="sub1">
      <xsl:call-template name="replace-substring">
        <xsl:with-param name="original" select="."/>
        <xsl:with-param name="substring" select=""&amp;""/>
        <xsl:with-param name="replacement" select=""^&amp;""/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="sub2">
      <xsl:call-template name="replace-substring">
        <xsl:with-param name="original" select="$sub1"/>
        <xsl:with-param name="substring" select=""|""/>
        <xsl:with-param name="replacement" select=""^|""/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:call-template name="replace-substring">
      <xsl:with-param name="original" select="$sub2"/>
      <xsl:with-param name="substring" select="$single-quote"/>
      <xsl:with-param name="replacement" select="$two-quotes"/>
    </xsl:call-template>
    <xsl:text>&#xA;</xsl:text>
  </xsl:template>
  <xsl:template name="replace-substring">
    <xsl:param name="original" />
    <xsl:param name="substring" />
    <xsl:param name="replacement" />
    <xsl:choose>
      <xsl:when test="contains($original, $substring)">
        <xsl:value-of 
          select="substring-before($original, $substring)" />
        <xsl:value-of select="$replacement" />
        <xsl:call-template name="replace-substring">
          <xsl:with-param name="original" 
            select="substring-after($original, $substring)" />
          <xsl:with-param 
            name="substring" select="$substring" />
          <xsl:with-param 
            name="replacement" select="$replacement" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$original" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>          
  
</xsl:stylesheet>
Output:
A
B
C


Variable without initialization

File: Data.xml
<?xml version="1.0" encoding="utf-8"?>
<data>    
    <animal>cat</animal>
    <animal>dog</animal>
  <animal>cow</animal>
</data>
File: Transform.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="color"/>
    <xsl:template match="//animal">
      <xsl:choose>
        <xsl:when test="boolean($color)">
          <P style="color:{$color}">
            <xsl:value-of select="."/>
          </P>
        </xsl:when>
        <xsl:otherwise>
          <paragraph>
            <xsl:value-of select="."/>
          </P>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="UTF-8"?>    
    <paragraph>cat</P>
    <paragraph>dog</P>
  <paragraph>cow</P>