#### 1.什么是 XSLT
- 可擴展樣式表轉換語言
- 用于將 XML 轉換為另一種格式的 XML 或者 HTML 或 XHTML,甚至 JSP 或 ASPX 等文本內容
- XSLT 使用 XPath 定位和導航 XML 文檔內容,并通過模板對 XML 進行轉換
- 模板定義了 XSLT 的轉換規則
#### 2.XPath
- 專用于在 XML 中查找信息的一種語言
- 常用于在 XML 文檔的元素和屬性之間進行導航
- 是 XSLT 的重要組成部分
- XPath 使用路徑表達式導航 XML 文檔
- XPath 包括一個標準函數庫
#### 3.XPath 術語
- 節點 (Nodes) – 包括元素、屬性、文本、命名空間、處理指令、注釋和文檔根元素。
- 原子值 (Atomic values) – 指沒有孩子和父母的節點。
- 條目 (Items) – 包括節點和原子值。
- 父母 (Parent) – 某節點的直接上級節點
- 孩子 (Children) – 某節點的直接下級節點
- 兄弟 (Siblings) – 某節點同一父母的同級節點
- 祖先 (Ancestors) – 某節點任意層次的上級節點
- 后代 (Descendants) – 某節點任意層次的下級節點
#### 4.XPath 語法 I
表達式 | 說明 | 示例
---|---|----
元素名 | 選擇當前元素下所有指定名字的子元素 | order
/ | 從文檔的根元素開始選擇元素 | /root/ancestor1
// | 選擇任何層次的元素 | //child1
. | 選擇當前元素 | .//child1
.. | 選擇父元素 | ../parent2
@ | 選擇屬性 | ../@name
* | 匹配所有元素 | /root/ancestor1/*
| | 或者 | //child1 | //child2
#### 5.XPath 語法 II
表達式 | 說明 | 示例
---|---|----
element[index] | 選擇當前元素下第index個element元素 | //parent[2]
element[@attr] | 選擇當前元素下擁有 attr 屬性的子元素 | //parent/*[@age]
element[@attr='value'] | 選擇當前元素下 attr 屬性值等于value的子元素 | //parent/*[@age>=58]
element[subElement='string'] | 選擇當前元素下 擁有子元素 subElement 且 subElement 的內容為 string 的元素
| //parent/*[descendant='B']
#### 6.XPath 操作符
表達式 | 說明 | 示例
---|---|----
+, - , * , div | 加、減、乘、除 | price div 10
=, != | 等于、不等于 | price div 10 = 8.8
>, >= | 大于、大于等于 | price >= 88
<, <= | 小于、小于等于 | price <= 88
or, and | 或者、并且 | price >=88 and price <= 99
mod | 取模 | price mod 2 = 1
#### 7.XSLT 的結構
- XSLT 聲明
- XSLT 模板
- <xsl:template>
- <xsl:apply-templates>
- XSLT 轉換規則
#### 8.XSLT 的聲明
```
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<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"
xmlns:xdt="http://www.w3.org/2005/xpath-datatypes">
<?xml-stylesheet type="text/xsl" href="cdcatalog.xsl"?>
```
#### 9.XSLT 的模板定義
- <xsl:template>
- name 屬性指定模板的名字
- match 屬性指示模板要匹配到 XML 文檔的哪些節點
- mode 屬性用于在 <apply-templates> 元素中區分相同匹配模式的模板
- priority 屬性指定模板的優先級
- <xsl:apply-templates>
- select 屬性指定一個 XPath 表達式用于選擇要套用模板的節點
- mode 屬性指定要使用哪個模板
```
<?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" xmlns:xdt="http://www.w3.org/2005/xpath-datatypes">
<!-- 轉換為html,編碼GB2312,不知為何,改成utf-8會亂碼 -->
<xsl:output method="html" version="4.0" encoding="GB2312" indent="yes"/>
<!-- 匹配到parent節點 -->
<xsl:template match="//parent">
<b>parent 節點</b><br/><hr/>
<xsl:apply-templates select="sibling" /><br/>
<xsl:apply-templates select="child" /><br/><hr/>
<!-- 使用X模板的child -->
<xsl:apply-templates select="child" mode="X"/><br/>
</xsl:template>
<xsl:template match="sibling">節點<br /></xsl:template>
<xsl:template match="child" mode="X">節點<br /></xsl:template>
</xsl:stylesheet>
```
#### 10.輸出信息
- <xsl:value-of> 元素可用于在 XSLT 模板中輸出節點的內容
- select 屬性指定要輸出的節點
- disable-output-escaping 屬性指示輸出時是否禁用 XML 轉義。 > < = 一類的 應該
- 如果輸出內容的目的地位于標簽的屬性中,則可以使用花括號{}來輸出內容
- 舉例
```
<font color="{@color}"><xsl:value-of select="@name" /></font>
```
#### 11.輸出標記和屬性
- <xsl:element> 元素用于產生并輸出一個標記
- name 屬性設置標記名
- namespace 屬性設置標記的命名空間
- use-attribute-sets 屬性可為標記引用一個屬性集
- <xsl:attribute> 元素用于產生并輸出一個標記的屬性
- name 屬性設置標記屬性的名稱
- namespace 屬性設置標記屬性的命名空間
- <xsl:attribute-set> 元素用于給標記定義屬性集
- name 屬性設置屬性集的名稱
- use-attribute-sets 屬性設置要引用的其它屬性集的名稱列表
```
<!-- 設置屬性集,屬性集名為FontAttributeSet,存儲字體屬性 -->
<xsl:attribute-set name="FontAttributeSet">
<!-- 分別設置字體屬性和顏色屬性 -->
<xsl:attribute name="face">黑體</xsl:attribute>
<xsl:attribute name="color">blue</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="HeadAttributeSet" use-attribute-sets="FontAttributeSet">
<xsl:attribute name="size">20px</xsl:attribute>
</xsl:attribute-set>
<xsl:template match="//parent">
<!-- 引用上面定義的HeadAttributeSet屬性集,由于HeadAttributeSet引用了FontAttributeSet屬性集,相當于一起引用了 -->
<xsl:element name="font" namespace="http://www.st-accp.com.cn/XML/"
use-attribute-sets="HeadAttributeSet">
<xsl:attribute name="style">text-decoration:underline;</xsl:attribute>
<!-- 可以這樣來取屬性值,例如@face -->
<xsl:value-of select="@name"/>
</xsl:element>
</xsl:template>
```
#### 12.其他輸出元素
- <xsl:text> 元素用于輸出文本節點
- <xsl:processing-instruction> 元素用于輸出處理指令
- <xsl:comment> 元素用于輸出注釋文本
- <xsl:number> 元素用于輸出格式化的數字
- level 屬性設置 count 屬性的統計方式
- count 屬性指示 XSLT 統計到當前位置某節點出現的次數,并且輸出該數量
- from 屬性指示使用 count 屬性統計時,開始計數的位置
- value 屬性指定要輸出的數字
- format 屬性指定數字輸出的格式,可選的值有(1, 01, a, A, i, I)
- grouping-separator 屬性指定數字分組的分隔符
- grouping-size 屬性指定每個數字分組的數字個數
#### 13.循環
- <xsl:for-each> 元素可對節點集中的每個節點進行循環處理
- select 屬性選取要循環處理的節點集
- <xsl:sort> 元素用于排序
- select 屬性選取作為排序依據的節點
- data-type 屬性指定節點值的數據類型,可選值包括(text, number, qname)
- order 屬性指示按升序或降序排序,可選值包括(ascending, descending)
- case-order 屬性指示按文本排序時大寫字母在前還是小寫字母在前,可選值包括(upper-first, lower-first)
```
<xsl:template match="book">
<xsl:for-each select="/title">
<xsl:sort select="." order="descending" />
<xsl:value-of select="." /><br/>
</xsl:for-each>
</xsl:template>
```
#### 14.分支
- <xsl:if> 元素用于條件分支
- test 屬性指定條件表達式
- <xsl:choose> 元素用于多路分支
- <xsl:when>
- test
- <xsl:otherwise>
```
<!-- 選擇book節點 -->
<xsl:template match="book">
<!-- 對title節點進行遍歷 -->
<xsl:for-each select="//title">
<!-- 選擇"." 節點,降序排序 -->
<xsl:sort select="." order="descending" />
<!-- 定義font元素 -->
<xsl:element name="font">
<!-- 定義font元素 color屬性 -->
<xsl:attribute name="color">
<!-- r如果position()對2取模為0,就藍色,否則紅色 -->
<xsl:if test="position() mod 2 = 0">blue</xsl:if>
<xsl:if test="position() mod 2 = 1">red</xsl:if>
</xsl:attribute>
<!-- 定義size元素 -->
<xsl:attribute name="size">
<xsl:choose>
<!-- 對3取模結果為1字體為40,結果為0則Large,否則為5 -->
<xsl:when test="position() mod 3 = 1">40</xsl:when>
<xsl:when test="position() mod 3 = 0">Large</xsl:when>
<xsl:otherwise>5</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<!-- 輸出 -->
<xsl:value-of select="." />
</xsl:element><br/>
</xsl:for-each>
</xsl:template>
```
#### 15.使用變量
- <xsl:variable> 元素可用于定義變量
- name 屬性指定變量名
- select 屬性指定作為變量值的表達式
- 使用變量可用 <xsl:valut-of> 元素
```
<!-- 定義變量,defaultSize,值為5 -->
<xsl:variable name="defaultSize" select="5" />
<!-- 使用變量 $變量名 -->
<xsl:value-of select="$defaultSize" />
```
#### 16.顯示調用模板
- <xsl:call-template> 元素可用于顯式調用模板
- name 屬性指定要調用的模板的名字
- <xsl:param> 元素可以在模板中定義參數
- name 屬性指定參數的名字
- select 屬性指定作為參數默認值的表達式
- <xsl:with-param> 元素用于在調用模板時傳遞參數給模板
- name 屬性指定參數名
- select 屬性指定參數值
```
<!-- 模板名為FontSizeTemplate -->
<xsl:template name="FontSizeTemplate">
<!-- 定義參數名為size,值為5 -->
<xsl:param name="size" select="5" />
<!-- 定義屬性名為size -->
<xsl:attribute name="size">
<xsl:choose>
<!-- 對3取模為1 則size為40,為0則為Large,否則為$defaultSize -->
<xsl:when test="position() mod 3 = 1">40</xsl:when>
<xsl:when test="position() mod 3 = 0">Large</xsl:when>
<xsl:otherwise><xsl:value-of select="$defaultSize" /></xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:template>
<xsl:call-template name="FontSizeTemplate">
<!-- 顯式調用模板,傳參給模板,參數為$defaultSize,這樣上面就可以使用這個參數了,但是這里我看不懂defaultSize是哪來的 -->
<xsl:with-param name="size" select="$defaultSize" />
</xsl:call-template>
```
#### 17.數字格式化
- 內置函數 format-number 可將數字轉換成格式化文本
- string format-number( number, format [, decimalformat])
```
<xsl:value-of select='format-number(8888.888, "###,###.00;(###,###.0)")' /><br/>
<xsl:value-of select='format-number(-8888.888, "###,###.00;(###,###.0)")' /><br/>
<xsl:value-of select='format-number(-8888.888, "###,###.00%")' /><br/>
```
#### 18.數字格式化設置
- <xsl:decimal-format> 元素用于format-number() 函數的數字格式化設置
- name 屬性指定此格式的名字
- decimal-separator 屬性指定小數點的符號
- grouping-separator 屬性指定數字分組的分隔符
- infinity 屬性指定當數字為無限大時要顯示的文字
- minus-sign 屬性指定負數符號
- NaN 屬性指定當值不是數字是要顯示的文字
- percent 屬性指定百分號的符號
- per-mille 屬性指定千分號的符號
- zero-digit 屬性指定數字"零"的符號
- digit 屬性指定需要顯示數字的位置的占位符
- pattern-separator 屬性指定用于分隔正數和負數格式模板的分隔符
#### 19.內置函數
XSLT | 1.0 | 內置函數
---|---|---
last() | starts-with(string,string) | true()
position() | contains(string,string) | false()
count(node-set) | substring-before(string,string) | number(object)
id(object) | substring-after(string,string) | sum(node-set)
local-name(node-set) | substring(string,number,number) | floor(number)
namespace-uri(node-set) | string-length(string) | ceiling(number)
name(node-set) | translate(string,string,string) | round(number)
string(object) | boolean(object) |
concat(string,string) | not(boolean) |
#### 20.OpenJawXPathAPI常用函數
- com.openjaw.xpath.OpenJawXPathAPI
- OpenJawXPathAPI函數,最多只能帶3個條件,且條件必須在同一節點層級,多用于屬性值判斷
- OpenJawXPathAPI.selectNodeList(node, xpath) -- 查找節點集合
- OpenJawXPathAPI.selectSingleNode(node, xpath) -- 查找單個節點
- OpenJawXPathAPI.selectSingleNodeAsBoolean(node, arg1, arg2) -- 選擇單一節點作為Boolean,這里都是翻譯,實際作用暫時不明
- OpenJawXPathAPI.selectSingleNodeAsFloat(node, arg1) -- 選擇單一節點作為浮點數
- OpenJawXPathAPI.selectSingleNodeAsInt(node, arg1) -- 選擇單一節點作為int
- OpenJawXPathAPI.selectSingleNodeAsString(node, xpath) -- 選擇單一節點作為String
```
OpenJawXPathAPI.selectSingleNodeAsString(msg, "UniqueID/@ID_Context")
OpenJawXPathAPI.selectNodeList(msg, "/OJT_Extensions/AirReservation/TravelerInfo/AirTraveler")
OpenJawXPathAPI.selectNodeList(msg, "AirItinerary/OriginDestinationOptions/OriginDestinationOption/FlightSegment[@RPH=" + 1 + "]")
OpenJawXPathAPI.selectSingleNodeAsBoolean(fareBreakdown, "PassengerFare/TPA_Extensions/Package", false)
OpenJawXPathAPI.selectSingleNodeAsInt(fareInfoRef, "PTC/@Quantity")
OpenJawXPathAPI.selectSingleNode(airTraveler, "PersonName")
OpenJawXPathAPI.selectSingleNodeAsFloat(fareBreakdown, "PassengerFare/BaseFare/@Amount")
```
#### 22.OJXPathHelper常用函數
- OJXPathHelper函數,可帶多個條件,且可多層級條件取值,該取值xpath需帶namespace
- OJXPathHelper.getNodeList(node, xpath)
- OJXPathHelper.getNode(node, xpath)
- OJXPathHelper.getBooleanean(node, arg1)
- OJXPathHelper.getInteger(node, arg1)
- OJXPathHelper.getInt(node, arg1)
- OJXPathHelper.getString(node, xpath)
```
boolean haveBeneficiary
= OJXPathHelper.getBoolean(superPNR,"count(ota:OJ_SuperPNR/ota:Customer[not(@Historic='true')]/ota:Additional/ota:CustLoyalty[@LoyalLevel='Beneficiary']) > 0");
Node couponPayment
= OJXPathHelper.getNode(msg, "ota:PaymentDetails/ota:Payments/ota:Payment[@Status='Paid' and @TransactionType='Debit' and ota:PaymentForm[ota:Other[@Type='210' and ota:Ref[@Code='OJ_SuperPNR_RPH']/text()='"+passRPH+"']]]");
NodeList payments
= OJXPathHelper.getNodeList(newSPNR, "/ota:OJ_SuperPNR/ota:PaymentDetails/ota:Payments/ota:Payment[@TransactionType = 'Debit' and ota:PaymentForm/ota:Other/@Type = '101']");
String seatBindAirProductNumber
= OJXPathHelper.getString(itineraryBean.getSuperPNR(),"/ota:OJ_SuperPNR/ota:ModularProduct[not(@Historic = 'true') and @ProductType='air' and @BookingStatus='booked']/@ProductNumber");
```
#### 23.xslt中使用自定義函數
```
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:config="http://xml.apache.org/xslt/java/com.openjawx.xRez.rendering.RenderingConfigBean"
xmlns:location="http://http://xml.apache.org/xslt/java/com.openjaw.console.location.LocationHierarchyBean"
xmlns:stringUtilities="xalan://com.openjaw.utils.StringUtilities">
<!-- 引用函數 -->
<xsl:value-of select="stringUtilities:replace($refundTimeThreshold,'-','')"/>
# 自定義函數
public static String replace(String originalStr, String searchStr, String replaceStr)
{
return "";
}
Travelsky-HU_Common 開發者自定義函數路徑 com.openjaw.utils.*
```