ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
#### 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.* ```