[XML]學習筆記(八)XSLT
阿新 • • 發佈:2019-02-09
一、XSL(eXtensible Stylesheet Language)擴充套件樣式表語言:主要包含三個部分——XSLT用於XML文件轉換,XPath用於在XML文件中導航,XSL-FO用於XML文件格式化。
b)<xsl:import href="sourcePath"/>和<xsl:import href="sourcePath"/>
在根元素下,第一個<xsl:template>之前植入,用於直接引用外部的其他xsl。
區別在於當定義的規則和正文中的規則衝突時,import的規則優先順序較低,include的規則優先順序與正文的規則相同。
如:原book.xsl中有
而另一個anotherBook.xsl中有include該檔案,則NewTitle是無效的,依舊使用原模板中的Title。如果採用import,則可以覆蓋原有book.xsl中的模板。
c)<xsl:template math=”…”>元素
每個xsl樣式表中至少包含一個,用於構造模板,match屬性的值是XPath表示式,用於為整個模板定義文件,其中採用”/” 表示定義整個文件。可選用屬性name,該屬性將在後面用於模板重用。
d)<xsl:apply-templates select="expression" mode="name">元素
把一個模板應用於當前元素或其子元素。
通過select屬性可以篩選匹配的元素或其子元素,*表示要選取整個節點集,省略該屬性時選取當前結點的所有子節點。預設情況下相當於select="text()",即選取文字。
通過mode屬性用來區分相同元素的不同處理方法。
其中<xsl:apply-templates/>是預設執行該模板,當在和葉子節點相關聯的模板中,可以不必寫明。
如:用對cd下的title和artist分別應用模板,模板cd、title和artist中省略了<xsl:apply-templates/>。
e)<xsl:value-of>元素
用於提取某個選定節點的內容,可以是文字、元素或者屬性,並把值新增到轉換的輸出流中。可擁有屬性select,該屬性的值為一個XPath表示式。
如:下面的xsl語句選出了catalog/cd/title和catalog/cd/artist的值。
f)<xsl:for-each>元素
用於選取指定節點集中的每個元素。與value-of類似,它也有select屬性,其值也是一個XPath表示式,當然在表示式中新增謂詞作為判別式也可以用來篩選元素。
如:下面的xsl語句選出了artist為Bob Dylan的cd資訊。
<xsl:for-each select="catalog/cd[artist='Bob Dylan']">
合法的比較運算子:= (等於),!= (不等於),< (小於),> (大於)
g)<xsl:sort>元素
用於對結果進行排序,緊跟<xsl:apply-templates>或<xsl:for-each>,是它們內部的一個元素,而不是屬性。
sort可以擁有以下屬性:
i.select="XPath",規定節點的排序關鍵字,即根據哪個節點/節點集排序。
ii.lang="language",規定排序所採用的語言。
iii.data-type = { "text" | "number" | QName },規定排序所採用的資料型別,預設為text。text是按所選節點的文字型別排序,即字典序;number則是按照所選節點的資料型別排序,如30,6,132按照text得到132,30,6,按照number得到6,30,132。
iv.order={"ascending"|"descending"},規定排序的順序,預設為"ascending"。
v.case-order={"upper-first"|"lower-first"},規定是否首先按照大寫/小寫字母排序,比如選用了lower-first,則對於book,Book,CZ,cz排序結果為book,Book,cz,CZ。
如:根據artist的值排序。
h)<xsl:if>元素
在<xsl:for-each>內部,它包含了一個“模板”,用於對XML文件內容的條件測試,只有在指定的條件成立時才會應用模板。
有且只有一個屬性test,該屬性的值為一個表示式,規定了要測試的條件。
如:找出售價大於10元的cd的名稱和作者。
以下xsl語句顯示的效果是最後一張cd的title輸出後面跟!,倒數第二張和最後一張cd的title之間用“,and”連線,其餘用逗號連線。
注意:xsl語句的每個if語句都會被測試!
i)<xsl:choose>元素
與<xsl:when>和<xsl:otherwise>結合,進行多重測試。只有when元素有且只有一個test屬性。
基本語法:
注意:when不會像if一樣對一個測試點進行多次測試,好比switch-case語句加上break。
如:一個名為color的變數,如果當前測試的元素有color屬性,則將color變數的值賦給當前測試元素的color屬性;否則,將color屬性置為green。
j)<xsl:call-template>元素:
<xsl:call-template name="templateName">用於實現模板重用。
k)<xsl:number/>元素:
用於測定當前節點在源文件中的位置,也可用於將格式化的數字插入結果樹。
i.count=”xPathExpression”:可選屬性,指定要計算的節點。
ii.level:可選屬性,控制如何分配序號。
1.single——預設,即每個序號只與所在層序號有關;
2.multiple——每個序號包含層級關係;
3.any——所有層共用一個序號關係。
iii.format:格式標記,可為1數字計數,01與1唯一的區別在於01~09,a表示小寫字母計數,A表示大寫字母計數,i表示小寫羅馬數字計數,I表示大寫羅馬數字計數。
iv.value:自己提供數字代替產生的序號;
grouping-separator:規定採用什麼符號來分割數字或組,預設為“,”;
grouping-size:規定分組的大小,預設為3。
如:
<xsl:number value="123456" grouping-separator="." grouping-size="2"/>
輸出為12.34.56
<xsl:number value="12" grouping-size="1" grouping-separator="#" format="I"/>
輸出為X#I#I,首先將12轉換成大寫羅馬數字XII,然後對其進行分割。
如源books.xml為:
目標輸出為:
轉換的xsl為:
如果將level選為single,則輸出結果如下:
1 First Chapter
2 Second Chapter
1 Subchapter 1
2 Subchapter 2
3 Third Chapter
1 Subchapter A
2 Subchapter B
1 subsub a
2 subsub b
如果將level選為any,則輸出結果如下:
1 First Chapter
2 Second Chapter
3 Subchapter 1
4 Subchapter 2
5 Third Chapter
6 Subchapter A
7 Subchapter B
8 subsub a
9 subsub b
l)<applet>屬性值模板:
如:
定義了傳遞給模板的引數的值,with-param的name屬性的值必須與所呼叫的模板的param的name屬性值相匹配,否則將被忽略。call-template和apply-templates中允許使用with-param元素。可以通過元素的內容設定引數值(如例子中),也可以通過select屬性賦值。
如:
輸入repeatTest.xml:
轉換repeatTest.xml:
輸出結果:
AAAAAAAAA
BBBBBB
用於宣告區域性變數/全域性變數,如果被宣告為頂層元素則是全域性的,如果在模板內部宣告則為區域性的。一旦設定了變數的值,就無法改變或修改該值,但可以通過其內容或select屬性向變數新增值。注意:如果設定了select屬性則variable不能包含任何內容了。
如:仍對上面的books.xml進行取每一層的最後一個chapter操作:
操作結果:注意Third Chapter被應用了此模板,因此遞迴呼叫。
Subchapter 2
Third Chapter
Subchapter A
Subchapter B
subsub a
subsub b
Subchapter B
subsub a
subsub b
subsub b
八、XSL中的key元素<xsl:key name="name" match="pattern" use="expression">
該元素是頂層元素,可以為指定的元素分配名稱和值對,通過key()函式在樣式表中使用。但此處的key不必是唯一的。
三個屬性均為必需的,name規定鍵的名稱,match規定鍵被應用到哪個節點,use指定要作為該鍵的值使用的表示式。
如定義一個鍵來尋找作者含有Jim Blue的書的所有作者:
源keyTest.xml:
輸出結果:
Jim Blue
Dan Farm
Blue Flowers
Mark Simp
Jim Blue
Green Trees
注意:XSL樣式表本身也是一個XML文件,所以第一行必須為XML宣告。
二、XSLT = XSLTransformations XSL轉換,可將一種XML文件轉換為另一種XML文件,或者說XSLT將XML源樹轉換為XML結果樹,通過使用XPath來定義源文件中可匹配一個或多個預定義模板部分,一旦匹配被找到,XSLT就會呼叫模板將源文件中的匹配部分轉換為結果文件。三、XSLT是一種閉包,它的輸入和輸出都是樹,可以管道化利用,如:文件1 -> 文件2-> 文件3。
四、XSLT語法:XSL樣式表由一個或多個模板(template)的規則組成,每個模板含有當前某個指定節點被匹配時所應用的規則。
a)<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">元素
XSLT的根元素,用於定義該文件是一個XSLT樣式表,上例中包含版本號以及XSLT名稱空間兩個屬性。其中stylesheet也可寫為transform,兩者是完全相同的。b)<xsl:import href="sourcePath"/>和<xsl:import href="sourcePath"/>
在根元素下,第一個<xsl:template>之前植入,用於直接引用外部的其他xsl。
區別在於當定義的規則和正文中的規則衝突時,import的規則優先順序較低,include的規則優先順序與正文的規則相同。
如:原book.xsl中有
<xsl:template match="title"> Title </xsl:template>
而另一個anotherBook.xsl中有include該檔案,則NewTitle是無效的,依舊使用原模板中的Title。如果採用import,則可以覆蓋原有book.xsl中的模板。
<xsl:include href="book.xsl">
(:<xsl:import href="book.xsl">:)
<xsl:template match="title">
NewTitle
</xsl:template>
c)<xsl:template math=”…”>元素
每個xsl樣式表中至少包含一個,用於構造模板,match屬性的值是XPath表示式,用於為整個模板定義文件,其中採用”/” 表示定義整個文件。可選用屬性name,該屬性將在後面用於模板重用。
d)<xsl:apply-templates select="expression" mode="name">元素
把一個模板應用於當前元素或其子元素。
通過select屬性可以篩選匹配的元素或其子元素,*表示要選取整個節點集,省略該屬性時選取當前結點的所有子節點。預設情況下相當於select="text()",即選取文字。
通過mode屬性用來區分相同元素的不同處理方法。
其中<xsl:apply-templates/>是預設執行該模板,當在和葉子節點相關聯的模板中,可以不必寫明。
如:用對cd下的title和artist分別應用模板,模板cd、title和artist中省略了<xsl:apply-templates/>。
<xsl:template match="cd"> <p> <xsl:apply-templates select="title"/> <xsl:apply-templates select="artist"/> </p> </xsl:template> <xsl:template match="title"> Title: <span style="color:#ff0000"> <xsl:value-of select="."/></span> <br /> </xsl:template> <xsl:template match="artist"> Artist: <span style="color:#00ff00"> <xsl:value-of select="."/></span> <br /> </xsl:template>
e)<xsl:value-of>元素
用於提取某個選定節點的內容,可以是文字、元素或者屬性,並把值新增到轉換的輸出流中。可擁有屬性select,該屬性的值為一個XPath表示式。
如:下面的xsl語句選出了catalog/cd/title和catalog/cd/artist的值。
<td><xsl:value-of select="catalog/cd/title"/></td>
<td><xsl:value-of select="catalog/cd/artist"/></td>
f)<xsl:for-each>元素
用於選取指定節點集中的每個元素。與value-of類似,它也有select屬性,其值也是一個XPath表示式,當然在表示式中新增謂詞作為判別式也可以用來篩選元素。
如:下面的xsl語句選出了artist為Bob Dylan的cd資訊。
<xsl:for-each select="catalog/cd[artist='Bob Dylan']">
合法的比較運算子:= (等於),!= (不等於),< (小於),> (大於)
g)<xsl:sort>元素
用於對結果進行排序,緊跟<xsl:apply-templates>或<xsl:for-each>,是它們內部的一個元素,而不是屬性。
sort可以擁有以下屬性:
i.select="XPath",規定節點的排序關鍵字,即根據哪個節點/節點集排序。
ii.lang="language",規定排序所採用的語言。
iii.data-type = { "text" | "number" | QName },規定排序所採用的資料型別,預設為text。text是按所選節點的文字型別排序,即字典序;number則是按照所選節點的資料型別排序,如30,6,132按照text得到132,30,6,按照number得到6,30,132。
iv.order={"ascending"|"descending"},規定排序的順序,預設為"ascending"。
v.case-order={"upper-first"|"lower-first"},規定是否首先按照大寫/小寫字母排序,比如選用了lower-first,則對於book,Book,CZ,cz排序結果為book,Book,cz,CZ。
如:根據artist的值排序。
<xsl:for-each select="catalog/cd">
<xsl:sort select="artist"/>
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
h)<xsl:if>元素
在<xsl:for-each>內部,它包含了一個“模板”,用於對XML文件內容的條件測試,只有在指定的條件成立時才會應用模板。
有且只有一個屬性test,該屬性的值為一個表示式,規定了要測試的條件。
如:找出售價大於10元的cd的名稱和作者。
<xsl:for-each select="catalog/cd">
<xsl:if test="price > 10">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:if>
</xsl:for-each>
以下xsl語句顯示的效果是最後一張cd的title輸出後面跟!,倒數第二張和最後一張cd的title之間用“,and”連線,其餘用逗號連線。
注意:xsl語句的每個if語句都會被測試!
<xsl:for-each select="catalog/cd">
<xsl:value-of select="title"/>
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:if test="position()=last()-1">
<xsl:text> and </xsl:text>
</xsl:if>
<xsl:if test="position()=last()">
<xsl:text>!</xsl:text>
</xsl:if>
</xsl:for-each>
i)<xsl:choose>元素
與<xsl:when>和<xsl:otherwise>結合,進行多重測試。只有when元素有且只有一個test屬性。
基本語法:
<xsl:choose>
<xsl:when test="expression">
... Output ...
</xsl:when>
<xsl:when test="expression">
... Output ...
</xsl:when>
<xsl:otherwise>
... Output ...
</xsl:otherwise>
</xsl:choose>
注意:when不會像if一樣對一個測試點進行多次測試,好比switch-case語句加上break。
如:一個名為color的變數,如果當前測試的元素有color屬性,則將color變數的值賦給當前測試元素的color屬性;否則,將color屬性置為green。
<xsl:variable name="color">
<xsl:choose>
<xsl:when test="@color">
<xsl:value-of select="@color"/>
</xsl:when>
<xsl:otherwise>green</xsl:otherwise>
</xsl:choose>
</xsl:variable>
j)<xsl:call-template>元素:
<xsl:call-template name="templateName">用於實現模板重用。
k)<xsl:number/>元素:
用於測定當前節點在源文件中的位置,也可用於將格式化的數字插入結果樹。
i.count=”xPathExpression”:可選屬性,指定要計算的節點。
ii.level:可選屬性,控制如何分配序號。
1.single——預設,即每個序號只與所在層序號有關;
2.multiple——每個序號包含層級關係;
3.any——所有層共用一個序號關係。
iii.format:格式標記,可為1數字計數,01與1唯一的區別在於01~09,a表示小寫字母計數,A表示大寫字母計數,i表示小寫羅馬數字計數,I表示大寫羅馬數字計數。
iv.value:自己提供數字代替產生的序號;
grouping-separator:規定採用什麼符號來分割數字或組,預設為“,”;
grouping-size:規定分組的大小,預設為3。
如:
<xsl:number value="123456" grouping-separator="." grouping-size="2"/>
輸出為12.34.56
<xsl:number value="12" grouping-size="1" grouping-separator="#" format="I"/>
輸出為X#I#I,首先將12轉換成大寫羅馬數字XII,然後對其進行分割。
如源books.xml為:
<?xml version="1.0" encoding="UTF-8"?>
<list>
<book ID="666">
<chapter>First Chapter</chapter>
<chapter>Second Chapter
<chapter>Subchapter 1</chapter>
<chapter>Subchapter 2</chapter>
</chapter>
<chapter>Third Chapter
<chapter>Subchapter A</chapter>
<chapter>Subchapter B
<chapter> subsub a</chapter>
<chapter> subsub b</chapter>
</chapter>
</chapter>
</book>
</list>
目標輸出為:
轉換的xsl為:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:template match="/">
<xsl:for-each select="//chapter">
<br/>
<xsl:number level="multiple" format="1.A.a "/>
<xsl:value-of select="./text()"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
如果將level選為single,則輸出結果如下:
1 First Chapter
2 Second Chapter
1 Subchapter 1
2 Subchapter 2
3 Third Chapter
1 Subchapter A
2 Subchapter B
1 subsub a
2 subsub b
如果將level選為any,則輸出結果如下:
1 First Chapter
2 Second Chapter
3 Subchapter 1
4 Subchapter 2
5 Third Chapter
6 Subchapter A
7 Subchapter B
8 subsub a
9 subsub b
l)<applet>屬性值模板:
如:
<applet>
<code class="Applet"/>
<codebase>/src/code</codebase>
</applet>
<xsl:template match="/">
<xsl:apply-templates select="applet">
<applet code="{code/@class}" codebase="{codebase}/java"/>
</xsl:apply-templates>
</xsl:stylesheet>
實際效果為:
<applet code="Applet" codebase="src/code/java"/>
五、XML與XSL關聯:
<?xml-stylesheet type="text/xsl" href="***.xslt"?>
六、XSL引數:<xsl:with-param name="…">定義了傳遞給模板的引數的值,with-param的name屬性的值必須與所呼叫的模板的param的name屬性值相匹配,否則將被忽略。call-template和apply-templates中允許使用with-param元素。可以通過元素的內容設定引數值(如例子中),也可以通過select屬性賦值。
如:
輸入repeatTest.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Name>
<AAA repeat="3"/>
<BBB repeat="2"/>
<CCC repeat="5"/>
</Name>
轉換repeatTest.xml:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:template match="/Name/*">
<p>
<xsl:call-template name="while">
<xsl:with-param name="test">
<xsl:value-of select="@repeat"/>
</xsl:with-param>
</xsl:call-template>
</p>
</xsl:template>
<xsl:template name="while">
<xsl:param name="test"/> #test記錄了repeat的次數
<xsl:value-of select="name()"/> #輸出AAA或BBB或CCC
<xsl:text/>
<xsl:if test="$test!=1"> #判斷當前repeat屬性是否為1
<xsl:call-template name="while">
<xsl:with-param name="test">
<xsl:value-of select="$test - 1"/> #遞迴呼叫while模板,引數修正為test值減1,注意$test和-、-和1之間均有空格
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
輸出結果:
AAAAAAAAA
BBBBBB
CCCCCCCCCCCCCCC
七、XSL變數:<xsl:variable name="…">用於宣告區域性變數/全域性變數,如果被宣告為頂層元素則是全域性的,如果在模板內部宣告則為區域性的。一旦設定了變數的值,就無法改變或修改該值,但可以通過其內容或select屬性向變數新增值。注意:如果設定了select屬性則variable不能包含任何內容了。
如:仍對上面的books.xml進行取每一層的最後一個chapter操作:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:variable name="totalChapters">
<xsl:value-of select="//chapter[last()]"/>
</xsl:variable>
<xsl:template match="/">
<xsl:value-of select="$totalChapters"/>
</xsl:template>
</xsl:stylesheet>
操作結果:注意Third Chapter被應用了此模板,因此遞迴呼叫。
Subchapter 2
Third Chapter
Subchapter A
Subchapter B
subsub a
subsub b
Subchapter B
subsub a
subsub b
subsub b
八、XSL中的key元素<xsl:key name="name" match="pattern" use="expression">
該元素是頂層元素,可以為指定的元素分配名稱和值對,通過key()函式在樣式表中使用。但此處的key不必是唯一的。
三個屬性均為必需的,name規定鍵的名稱,match規定鍵被應用到哪個節點,use指定要作為該鍵的值使用的表示式。
如定義一個鍵來尋找作者含有Jim Blue的書的所有作者:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:key name="findAuthor" match="list/book" use="author"/>
<xsl:param name="author">Jim Blue</xsl:param>
<xsl:template match="/">
<xsl:copy-of select="key('findAuthor', $author)"/>
</xsl:template>
</xsl:stylesheet>
源keyTest.xml:
<?xml version="1.0" encoding="UTF-8"?>
<list>
<book ID="234">
<author>Jim Blue</author>
<author>Dan Farm</author>
<author>Blue Flowers</author>
</book>
<book ID="666">
<author>Mark Simp</author>
<author>Jim Blue</author>
<author>Green Trees</author>
</book>
<book ID="898">
<author>Jay Bart</author>
<author>Red Tulips</author>
</book>
</list>
輸出結果:
Jim Blue
Dan Farm
Blue Flowers
Mark Simp
Jim Blue
Green Trees
九、通過XSLT與XQuery生成HTML
給定students.xml檔案,按照出生年月日排序,學號為Z00123101的學生資訊用綠色顯示,學號為Z00123102的學生資訊用藍色顯示,其餘用紅色顯示。
如
源students.xml檔案:
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="Z00123101">
<name>The No.1 student</name>
<birthday>1987.2</birthday>
<phone>62220001</phone>
</student>
<student id="Z00123102">
<name>the No.2 student</name>
<birthday>1975.6</birthday>
<phone>62220002</phone>
</student>
<student id="Z00123103">
<name>the No.3 student</name>
<birthday>1978.8</birthday>
<phone>62220003</phone>
</student>
<student id="Z00123104">
<name>the No.4 student</name>
<birthday>1976.2</birthday>
<phone>62220004</phone>
</student>
</students>
通過XSLT生成:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<html>
<head>
<table border="1" cols="4" width="100%">
<tr>
<th>No</th>
<th>Name</th>
<th>Phone</th>
<th>Birthday</th>
</tr>
<xsl:for-each select="students/student">
<xsl:sort select="birthday"/>
<xsl:choose>
<xsl:when test="@id='Z00123101'">
<tr style="color:green">
<td><xsl:value-of select="@id"/></td>
<xsl:apply-templates select="name|phone"/>
<xsl:apply-templates select="birthday"/>
</tr>
</xsl:when>
<xsl:when test="@id='Z00123102'">
<tr style="color:blue">
<td><xsl:value-of select="@id"/></td>
<xsl:apply-templates select="name|phone"/>
<xsl:apply-templates select="birthday"/>
</tr>
</xsl:when>
<xsl:otherwise>
<tr style="color:red">
<td><xsl:value-of select="@id"/></td>
<xsl:apply-templates select="name|phone"/>
<xsl:apply-templates select="birthday"/>
</tr>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</table>
</head>
<body></body>
</html>
</xsl:template>
<xsl:template match="name|phone|birthday">
<td><xsl:value-of select="."></xsl:value-of></td>
</xsl:template>
</xsl:stylesheet>
通過XQuery生成:
xquery version "1.0";
<html>
<head>
<table border="1" cols="4" width="100%">
<tr>
<th>No</th>
<th>Name</th>
<th>Phone</th>
<th>Birthday</th>
</tr>
{
for $x in doc("students.xml")/students/student
order by $x/birthday
return if(data($x/@id)="Z00123102")
then <tr style="color:blue">
<td>{data($x/@id)}</td>
<td>{data($x/name)}</td>
<td>{data($x/phone)}</td>
<td>{data($x/birthday)}</td>
</tr>
else if(data($x/@id)="Z00123101")
then <tr style="color:green">
<td>{data($x/@id)}</td>
<td>{data($x/name)}</td>
<td>{data($x/phone)}</td>
<td>{data($x/birthday)}</td>
</tr>
else <tr style="color:red">
<td>{data($x/@id)}</td>
<td>{data($x/name)}</td>
<td>{data($x/phone)}</td>
<td>{data($x/birthday)}</td>
</tr>
}
</table>
</head>
<body/>
</html>