XML Tutorial/XSLT stylesheet/template — различия между версиями

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

Текущая версия на 11:26, 26 мая 2010

Содержание

A template can match from a selection of location paths, individual paths being separated with "|".

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="utf-8"?> <employee>

 <firstName>Joe</firstName>
 <surname>Smith</surname>

</employee> 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:template match="firstName|surname">
     <xsl:text>[template: </xsl:text>
     <xsl:value-of select="name()" />
     <xsl:text> outputs </xsl:text>
     <xsl:apply-templates />
     <xsl:text> ]</xsl:text>
 </xsl:template>

</xsl:stylesheet> Output: <?xml version="1.0" encoding="UTF-8"?>

[template: firstName outputs Joe ]
[template: surname outputs Smith ]
</source>


Call template based function recursively

   <source lang="xml">

File: Data.xml <?xml version="1.0"?> <numbers>

 <x>4</x>
 <y>3.2</y>
 <z>11</z>

</numbers> 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" />
 <xsl:variable name="iterations" select="8" />
 <xsl:template name="myFunction">
   <xsl:param name="i">1</xsl:param>
   <xsl:param name="myValue">0</xsl:param>
   <xsl:choose>
     <xsl:when test="$i <= $iterations">
       <xsl:call-template name="myFunction">
         <xsl:with-param name="i" select="$i + 4" />
         <xsl:with-param name="myValue"
           select="$myValue + (4 div $i)" />
       </xsl:call-template>
     </xsl:when>
     <xsl:otherwise>
       <xsl:value-of select="$myValue" />
     </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
 <xsl:template match="/">
   <xsl:call-template name="myFunction" />
 </xsl:template>

</xsl:stylesheet> Output: 4.8</source>


If you want to include descendants of the node, you have to explicitly request their templates.

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="utf-8"?>

   <AAA id="a1" pos="start">
     <BBB id="b1"/>
     <BBB id="b2"/>
   </AAA>
   <AAA id="a2">
     <BBB id="b3"/>
     <BBB id="b4"/>
     <CCC id="c1">
       <DDD id="d1"/>
     </CCC>
     <BBB id="b5">
       <CCC id="c2"/>
     </BBB>
   </AAA>

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:template match="/">
     <xsl:apply-templates/>
   </xsl:template>
   <xsl:template match="/data">
     <xsl:apply-templates/>
   </xsl:template>
   <xsl:template match="AAA">
       <xsl:value-of select="name()"/>
       <xsl:text> id=</xsl:text>
       <xsl:value-of select="@id"/>
     <xsl:apply-templates/>
   </xsl:template>
   <xsl:template match="BBB">
       <xsl:value-of select="name()"/>
       <xsl:text> id=</xsl:text>
       <xsl:value-of select="@id"/>
     <xsl:apply-templates/>
   </xsl:template>
   <xsl:template match="CCC">
       <xsl:value-of select="name()"/>
       <xsl:text> id=</xsl:text>
       <xsl:value-of select="@id"/>
     <xsl:apply-templates/>
   </xsl:template>
   <xsl:template match="DDD">
       <xsl:value-of select="name()"/>
       <xsl:text> id=</xsl:text>
       <xsl:value-of select="@id"/>
   </xsl:template>

</xsl:stylesheet> Output: <?xml version="1.0" encoding="UTF-8"?>

AAA id=a1
BBB id=b1
BBB id=b2
AAA id=a2
BBB id=b3
BBB id=b4
CCC id=c1
DDD id=d1
BBB id=b5
CCC id=c2
</source>


Mark a parameter as requred

   <source lang="xml">

File: Transform.xslt <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="2.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:template match="/">
   <xsl:call-template name="date-formatter">
     <xsl:with-param name="date" select="current-date()"/>
   </xsl:call-template>
 </xsl:template>
 <xsl:template name="date-formatter">
   <xsl:param name="date" required="yes"/>
   <xsl:value-of select="format-date($date, "[M01]/[D01]/[Y0001]")"/>
 </xsl:template>

</xsl:stylesheet>

Output: 12/11/2008</source>


match=county[starts-with(.,K)]

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="US-ASCII"?> <state name="New York">

<county>Bristol</county>
<county>Kent</county>
<county>Newport</county>
<county>Providence</county>
<county>Washington</county>

</state>

File: Transform.xslt <?xml version="1.0" encoding="US-ASCII"?> <xsl:stylesheet version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" indent="yes" />
 <xsl:template match="/">
   <county state="{state/@name}">
     <xsl:apply-templates select="state" />
   </county>
 </xsl:template>
 <xsl:template match="state">
   <xsl:apply-templates select="county" />
 </xsl:template>
 <xsl:template match="county[starts-with(.,"K")]">
   <first-match>
     <xsl:apply-templates />
   </first-match>
 </xsl:template>
 <xsl:template match="county[2]">
   <last-match>
     <xsl:apply-templates />
   </last-match>
 </xsl:template>
 <xsl:template match="county">
   <name>
     <xsl:apply-templates />
   </name>
 </xsl:template>

</xsl:stylesheet> Output: <?xml version="1.0" encoding="UTF-8"?> <county state="New York">

  <name>Bristol</name>
  <last-match>Kent</last-match>
  <name>Newport</name>
  <name>Providence</name>
  <name>Washington</name>

</county></source>


Parts of XML document to which template should be applied are determined by location paths

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="utf-8"?>

   <AAA id="a1" pos="start">
     <BBB id="b1"/>
     <BBB id="b2"/>
   </AAA>
   <AAA id="a2">
     <BBB id="b3"/>
     <BBB id="b4"/>
     <CCC id="c1">
       <DDD id="d1"/>
     </CCC>
     <BBB id="b5">
       <CCC id="c2"/>
     </BBB>
   </AAA>

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:template match="BBB">
       <xsl:value-of select="name()"/>
       <xsl:text> id=</xsl:text>
       <xsl:value-of select="@id"/>
   </xsl:template>
   <xsl:template match="/source/AAA/CCC/DDD">

<xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/>

   </xsl:template>

</xsl:stylesheet> Output: <?xml version="1.0" encoding="UTF-8"?>

BBB id=b1
BBB id=b2


BBB id=b3
BBB id=b4


BBB id=b5
</source>


Processing always starts with the template match="/"

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="utf-8"?>

   <AAA id="a1" pos="start">
     <BBB id="b1"/>
     <BBB id="b2"/>
   </AAA>
   <AAA id="a2">
     <BBB id="b3"/>
     <BBB id="b4"/>
     <CCC id="c1">
       <DDD id="d1"/>
     </CCC>
     <BBB id="b5">
       <CCC id="c2"/>
     </BBB>
   </AAA>

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:template match="AAA">
       <xsl:value-of select="name()"/>
       <xsl:text> id=</xsl:text>
       <xsl:value-of select="@id"/>
   </xsl:template>

</xsl:stylesheet> Output: <?xml version="1.0" encoding="UTF-8"?>

AAA id=a1
AAA id=a2
</source>


template match=state priority=2

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="US-ASCII"?> <state name="New York">

<county>Bristol</county>
<county>Kent</county>
<county>Newport</county>
<county>Providence</county>
<county>Washington</county>

</state>

File: Transform.xslt <?xml version="1.0" encoding="US-ASCII"?> <xsl:stylesheet version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" indent="yes" />
 <xsl:template match="/">
   <county state="{state/@name}">
     <xsl:apply-templates select="state" />
   </county>
 </xsl:template>
 <xsl:template match="state" priority="2">
   <xsl:apply-templates select="county" />
 </xsl:template>
 <xsl:template match="state" priority="1">
   <xsl:apply-templates select="county[starts-with(.,"K")]" />
 </xsl:template>
 <xsl:template match="county">
   <name>
     <xsl:apply-templates />
   </name>
 </xsl:template>

</xsl:stylesheet> Output: <?xml version="1.0" encoding="UTF-8"?> <county state="New York">

  <name>Bristol</name>
  <name>Kent</name>
  <name>Newport</name>
  <name>Providence</name>
  <name>Washington</name>

</county></source>


Template with parameters

   <source lang="xml">

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:call-template name="test">
     <xsl:with-param name="param1" select=""57""/>
     <xsl:with-param name="param2" select=""93""/>
   </xsl:call-template>
 </xsl:template>
 <xsl:template name="test">
   <xsl:param name="param1"/>
   <xsl:text>Value of $param1: </xsl:text>
   <xsl:value-of select="$param1"/>
 </xsl:template>

</xsl:stylesheet> Output: Value of $param1: 57</source>


the default action in the absence of priority attributes.

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="utf-8"?>

   <AAA id="a1" pos="start">
     <BBB id="b1"/>
     <BBB id="b2"/>
   </AAA>
   <AAA id="a2">
     <BBB id="b3"/>
     <BBB id="b4"/>
     <CCC id="c1">
       <CCC id="c2"/>
     </CCC>
     <BBB id="b5">
       <CCC id="c3"/>
     </BBB>
   </AAA>

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:template match="/">
     <xsl:apply-templates select="//CCC"/>
   </xsl:template>
   <xsl:template match="CCC">

<xsl:value-of select="name()"/> <xsl:text> (id=</xsl:text> <xsl:value-of select="@id"/> <xsl:text>)</xsl:text>

   </xsl:template>
   <xsl:template match="CCC/CCC">

<xsl:value-of select="name()"/> <xsl:text> (id=</xsl:text> <xsl:value-of select="@id"/> <xsl:text>)</xsl:text>

   </xsl:template>

</xsl:stylesheet> Output:

<?xml version="1.0" encoding="UTF-8"?>

CCC (id=c1)

CCC (id=c2)

CCC (id=c3)

</source>


This priority order can be specified with the priority attributte.

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="utf-8"?>

   <AAA id="a1" pos="start">
     <BBB id="b1"/>
     <BBB id="b2"/>
   </AAA>
   <AAA id="a2">
     <BBB id="b3"/>
     <BBB id="b4"/>
     <CCC id="c1">
       <CCC id="c2"/>
     </CCC>
     <BBB id="b5">
       <CCC id="c3"/>
     </BBB>
   </AAA>

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:template match="/">
     <xsl:apply-templates select="//CCC"/>
   </xsl:template>
   <xsl:template match="CCC" priority="3">

<xsl:value-of select="name()"/> <xsl:text> (id=</xsl:text> <xsl:value-of select="@id"/> <xsl:text>)</xsl:text>

   </xsl:template>
   <xsl:template match="CCC/CCC" priority="4">

<xsl:value-of select="name()"/> <xsl:text> (id=</xsl:text> <xsl:value-of select="@id"/> <xsl:text>)</xsl:text>

   </xsl:template>

</xsl:stylesheet> Output:

<?xml version="1.0" encoding="UTF-8"?>

CCC (id=c1)

CCC (id=c2)

CCC (id=c3)

</source>


When a template for the node exists, there is no default processing invoked

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="utf-8"?> <AAA id="a1" pos="start">

     <BBB id="b1"/>
     <BBB id="b2"/>
   </AAA>
   <AAA id="a2">
     <BBB id="b3"/>
     <BBB id="b4"/>
     <CCC id="c1">
       <DDD id="d1"/>
     </CCC>
     <BBB id="b5">
       <CCC id="c2"/>
     </BBB>
   </AAA>

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:template match="AAA">
       <xsl:value-of select="name()"/>
       <xsl:text> id=</xsl:text>
       <xsl:value-of select="@id"/>
   </xsl:template>
   <xsl:template match="BBB">
       <xsl:value-of select="name()"/>
       <xsl:text> id=</xsl:text>
       <xsl:value-of select="@id"/>
   </xsl:template>
   <xsl:template match="CCC">
       <xsl:value-of select="name()"/>
       <xsl:text> id=</xsl:text>
       <xsl:value-of select="@id"/>
   </xsl:template>
   <xsl:template match="DDD">
       <xsl:value-of select="name()"/>
       <xsl:text> id=</xsl:text>
       <xsl:value-of select="@id"/>
   </xsl:template>

</xsl:stylesheet> Output:

<?xml version="1.0" encoding="UTF-8"?>
AAA id=a1
AAA id=a2
</source>


While XSLT does not define while and for loops, their behavior can be simulated.

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="utf-8"?>

   <AAA repeat="3"/>
   <BBB repeat="2"/>
   <CCC repeat="5"/>

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:template match="/data/*">
     <paragraph>
       <xsl:call-template name="for">
         <xsl:with-param name="stop">
           <xsl:value-of select="@repeat"/>
         </xsl:with-param>
       </xsl:call-template>
     </p>
   </xsl:template>
   <xsl:template name="for">
     <xsl:param name="start">1</xsl:param>
     <xsl:param name="stop">1</xsl:param>
     <xsl:param name="step">1</xsl:param>
     <xsl:value-of select="name()"/>
     <xsl:text/>
     <xsl:if test="$start < $stop">
       <xsl:call-template name="for">
         <xsl:with-param name="stop">
           <xsl:value-of select="$stop"/>
         </xsl:with-param>
         <xsl:with-param name="start">
           <xsl:value-of select="$start + $step"/>
         </xsl:with-param>
       </xsl:call-template>
     </xsl:if>
   </xsl:template>

</xsl:stylesheet> Output: <?xml version="1.0" encoding="UTF-8"?>

   <paragraph>AAAAAAAAA</p>
   <paragraph>BBBBBB</p>
   <paragraph>CCCCCCCCCCCCCCC</p></source>
   
  

With modes an element can be processed multiple times, each time producing a different result.

   <source lang="xml">

In <stylesheet id="id3"/> one of the modes does not exist. File: Data.xml <?xml version="1.0" encoding="utf-8"?>

   <AAA id="a1" pos="start">
     <BBB id="b1"/>
     <BBB id="b2"/>
   </AAA>
   <AAA id="a2">
     <BBB id="b3"/>
     <BBB id="b4"/>
     <CCC id="c1">
       <CCC id="c2"/>
     </CCC>
     <BBB id="b5">
       <CCC id="c3"/>
     </BBB>
   </AAA>

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:template match="/">
     <xsl:apply-templates select="//CCC" mode="red"/>
     <xsl:apply-templates select="//CCC" mode="blue"/>
     <xsl:apply-templates select="//CCC"/>
   </xsl:template>
   <xsl:template match="CCC" mode="red">
       <xsl:value-of select="name()"/>
       <xsl:text> id=</xsl:text>
       <xsl:value-of select="@id"/>
   </xsl:template>
   <xsl:template match="CCC" mode="blue">
       <xsl:value-of select="name()"/>
       <xsl:text> id=</xsl:text>
       <xsl:value-of select="@id"/>
   </xsl:template>
   <xsl:template match="CCC">
       <xsl:value-of select="name()"/>
       <xsl:text> id=</xsl:text>
       <xsl:value-of select="@id"/>
   </xsl:template>

</xsl:stylesheet> Output:

<?xml version="1.0" encoding="UTF-8"?>
CCC id=c1
CCC id=c2
CCC id=c3
CCC id=c1
CCC id=c2
CCC id=c3
CCC id=c1
CCC id=c2
CCC id=c3
</source>


without if

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="ISO-8859-1"?> <africa>

<nation>
 <name>Algeria</name>
 <capital>Algiers</capital>
 <population>32277942</population>
 <cc>dz</cc>
</nation>

</africa> File: Transform.xslt <?xml version="1.0" encoding="US-ASCII"?> <xsl:stylesheet version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text" />
 <xsl:template match="africa">
   <xsl:apply-templates select="nation" />
 </xsl:template>
 <xsl:template match="nation[population <= 10000000]">
   <xsl:text> * </xsl:text>
   <xsl:value-of select="name" />
   <xsl:text> (<= 10M)</xsl:text>
   <xsl:text>
</xsl:text>
 </xsl:template>
 <xsl:template match="nation[population > 10000000]">
   <xsl:text> * </xsl:text>
   <xsl:value-of select="name" />
   <xsl:text> (> 10M)</xsl:text>
   <xsl:text>
</xsl:text>
 </xsl:template>

</xsl:stylesheet> Output:

* Algeria (> 10M)</source>
   
  

xsl:template match="/"

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="utf-8"?>

 <element>Fe</element>
 <element>Cl</element>
 <element>Br</element>
 <element>I</element>
 <element>Ni</element>
 <element>H</element>
 <element>Po</element>
 <element>S</element>
 <element>O</element>

File: Transform.xslt <?xml version="1.0"?> <xsl:stylesheet version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="/">
   <xsl:copy/>
 </xsl:template>

</xsl:stylesheet></source>