#### 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.*
```