2009年5月3日

XPath 比較運算

若要比較 XPath 中的兩個物件,請使用 = 符號來測試是否相等,或使用 != 測試是否不相等。
若是比較運算,必須只能提供兩個運算元。接下來評估每個運算元以進行比較,再視需要予以轉換,讓它們擁有相同的型別。這個動作會根據底下說明的處理程序<比較優先順序>執行。
所有項目和屬性都是字串,但對於數字比較,則會自動轉換成整數值。在比較運算期間,常值數值會轉換成 long 或 double 型別,如下列表格所示。
如需 < 及其他二進位比較運算子的詳細資訊,請參閱底下的「二進位比較運算子」。

常值型別 比較 範例
String  text(lvalue) op text(rvalue)   a &lt; GGG 
Integer  (long) lvalue op (long) rvalue   a &lt; 3 
Real  (double) lvalue op (double) rvalue   a &lt; 3.1 

可在運算式中將單引號或雙引號當做字串分隔符號 (Delimiter)。這能更容易從指令碼語言中建構和傳遞模式。
範例
運算式 表示
 author[last-name = "Bob"]  內含至少一個  <last-name>  項目 (含值  Bob ) 的所有  <author>  項目。
 author[last-name[1] = "Bob"]  擁有值  Bob  的第一個  <last-name>  子項目所屬的所有  <author>  項目。
 author/degree[@from != "Harvard"]  包含  <degree>  項目 (含有不等於  "Harvard"  的  from  屬性) 的所有  <author>  項目。
 author[last-name = /editor/last-name]  包含  <last-name>  項目 (這些項目與根項目下的  <editor>  項目內部之  <last-name>  項目相同) 的所有  <author>  項目。
 author[. = "Matthew Bob"]  字串值為  Matthew Bob  的所有  <author>  項目。


比較優先順序
資料型別的相關比較會遵循優先順序。
IF 至少有一個運算元是布林值 THEN 將每一個運算元轉換成布林值
ELSE IF 至少有一個運算元是數字 THEN 將每一個運算元轉換成數字
ELSE IF 至少有一個運算元是日期 THEN 將每一個運算元轉換成日期
ELSE 將兩個運算元轉換成字串。

二進位比較運算子

一組二進位比較運算子會比較數字和字串並傳回布林值結果。<、<=、> 和 >= 運算子分別用於小於、小於或等於、大於,以及大於或等於。可在運算式中將單引號或雙引號當做字串分隔符號。這使得從指令碼語言中建構和傳遞模式變得更容易。

範例
運算式 表示
 author[last-name = "Bob" and price &gt; 50]  內含  <last-name>  項目 (含值  Bob ) 和  <price>  項目 (其值大於 50) 的所有  <author>  項目。
 degree[@from != "Harvard"]  包含不等於  "Harvard"  的  from  屬性之所有  <degree>  項目。
 author[last-name &gt;= "M"]  包含  <last-name>  項目 (其值以字母 M 或之後的字母開頭) 的所有  <author>  項目。
 book[position() &lt;= 3]  XML 檔中的前三個  <book>  項目 (1、2、3)。


範例
XML
<?xml version="1.0"?>
<test>
<x a="1">
<x a="2" b="B">
<x>
<y>y31</y>
<y>y32</y>
</x>
</x>
</x>

<x a="2">
<y>y2</y>
</x>

<x a="3">
<y>y3</y>
</x>
</test>


XSLT
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<!-- Suppress text nodes not covered in subsequent template rule. -->
<xsl:template match="text()"/>
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:apply-templates select="*|@*"/>
<xsl:if test="text()">
<xsl:value-of select="."/>
</xsl:if>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="/test">
<xsl:apply-templates select="//x[position() = 1 ] "/>
</xsl:template>
</xsl:stylesheet>


輸出結果
<x a="1">
<x a="2" b="B">
<x>
<y>y31</y>
<y>y32</y>
</x>
</x>
</x>
<x a="2" b="B">
<x>
<y>y31</y>
<y>y32</y>
</x>
</x>
<x>
<y>y31</y>
<y>y32</y>
</x>