• XSLT2.0实用的新功能 .(转)


    转自:http://blog.csdn.net/crystalbruce/article/details/7407631

    2007年1月,W3C发布了XSLT2.0规范,2009年发布了XSLT2.1,XSLT3.0预计今年发布得意

    分组

    函数:node-set current-group():该函数返回分组所包含的节点集。

    函数:node-set current-grouping-key():该函数返回当前分组的条件(控制分分组的关键节点)。

    <!-- Category: instruction -->
    <xsl:for-each-group
      select
    = expression
      group-by? = expression
      group-adjacent? = expression
      group-starting-with? = pattern
      group-ending-with? = pattern
      collation? = { uri }>
      <!-- Content: (xsl:sort*, sequence-constructor) -->
    </xsl:for-each-group>

     

    属性详解:

    1:select:用于指定需要分组的节点;

    2:group-by:用于控制分组的关键节点;

    3:group-adjacent:用于控制分组的关键节点,并且只将相邻的元素分为一组;

    4:group-starting-with:指定分组的开始节点;

    5:group-ending-with:指定分组的结束节点;

    Example: Grouping Nodes based on Common Values

    The following example groups a list of nodes based on common values. The resulting groups are numbered but unsorted, and a total is calculated for each group.

    Source XML document:

    1. <cities>  
    2.   <city name="Milano"  country="Italia"      pop="5"/>  
    3.   <city name="Paris"   country="France"      pop="7"/>  
    4.   <city name="München" country="Deutschland" pop="4"/>  
    5.   <city name="Lyon"    country="France"      pop="2"/>  
    6.   <city name="Venezia" country="Italia"      pop="1"/>  
    7. </cities>  
    <cities>
      <city name="Milano"  country="Italia"      pop="5"/>
      <city name="Paris"   country="France"      pop="7"/>
      <city name="München" country="Deutschland" pop="4"/>
      <city name="Lyon"    country="France"      pop="2"/>
      <city name="Venezia" country="Italia"      pop="1"/>
    </cities>
    

    Desired output:

    1. <table>  
    2.   <tr>  
    3.     <th>Position</th>  
    4.     <th>Country</th>  
    5.     <th>List of Cities</th>  
    6.     <th>Population</th>  
    7.   </tr>  
    8.   <tr>  
    9.     <td>1</td>  
    10.     <td>Italia</td>  
    11.     <td>Milano, Venezia</td>  
    12.     <td>6</td>  
    13.   </tr>  
    14.   <tr>  
    15.     <td>2</td>  
    16.     <td>France</td>  
    17.     <td>Lyon, Paris</td>  
    18.     <td>9</td>  
    19.   </tr>    
    20.   <tr>  
    21.     <td>3</td>  
    22.     <td>Deutschland</td>  
    23.     <td>München</td>  
    24.     <td>4</td>  
    25.   </tr>    
    26. </table>  
    <table>
      <tr>
        <th>Position</th>
        <th>Country</th>
        <th>List of Cities</th>
        <th>Population</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Italia</td>
        <td>Milano, Venezia</td>
        <td>6</td>
      </tr>
      <tr>
        <td>2</td>
        <td>France</td>
        <td>Lyon, Paris</td>
        <td>9</td>
      </tr>  
      <tr>
        <td>3</td>
        <td>Deutschland</td>
        <td>München</td>
        <td>4</td>
      </tr>  
    </table>
    

    Solution:

    1. <table xsl:version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
    2.   <tr>  
    3.     <th>Position</th>  
    4.     <th>Country</th>  
    5.     <th>City List</th>  
    6.     <th>Population</th>  
    7.   </tr>  
    8.   <xsl:for-each-group select="cities/city" group-by="@country">  
    9.     <tr>  
    10.       <td><xsl:value-of select="position()"/></td>  
    11.       <td><xsl:value-of select="@country"/></td>  
    12.       <td>  
    13.         <xsl:value-of select="current-group()/@name" separator=", "/>  
    14.       </td>  
    15.       <td><xsl:value-of select="sum(current-group()/@pop)"/></td>  
    16.     </tr>  
    17.   </xsl:for-each-group>  
    18. </table>  
    <table xsl:version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <tr>
        <th>Position</th>
        <th>Country</th>
        <th>City List</th>
        <th>Population</th>
      </tr>
      <xsl:for-each-group select="cities/city" group-by="@country">
        <tr>
          <td><xsl:value-of select="position()"/></td>
          <td><xsl:value-of select="@country"/></td>
          <td>
            <xsl:value-of select="current-group()/@name" separator=", "/>
          </td>
          <td><xsl:value-of select="sum(current-group()/@pop)"/></td>
        </tr>
      </xsl:for-each-group>
    </table>
    

     

    自定义函数

    <!-- Category: declaration -->
    <xsl:function
      name = qname
      as? = sequence-type
      override? = "yes" | "no">
      <!-- Content: (xsl:param*, sequence-constructor) -->
    </xsl:function>

    属性详解:

    1:name:函数名;

    2:as:函数的返回值;

    3:override:当存在同名函数时,是否覆盖。

    <funciton.../>中可包含N个<param.../>子元素,用于为该函数定义形参。

    <!-- Category: declaration -->
    <xsl:param
      name = qname
      select? = expression
      as? = sequence-type
      required? = "yes" | "no"
      tunnel? = "yes" | "no">
      <!-- Content: sequence-constructor -->
    </xsl:param>

    属性详解:

    as:指定形参的数据类型;

    tunnel:默认是no,用于指定该参数是一个tunnel参数。

    Example: A Stylesheet Function

    The following example creates a recursive stylesheet function named str:reverse that reverses the words in a supplied sentence, and then invokes this function from within a template rule.

    1. <xsl:transform   
    2.   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
    3.   xmlns:xs="http://www.w3.org/2001/XMLSchema"  
    4.   xmlns:str="http://example.com/namespace"  
    5.   version="2.0"  
    6.   exclude-result-prefixes="str">  
    7.   
    8. <xsl:function name="str:reverse" as="xs:string">  
    9.   <xsl:param name="sentence" as="xs:string"/>  
    10.   <xsl:sequence    
    11.      select="if (contains($sentence, ' '))  
    12.              then concat(str:reverse(substring-after($sentence, ' ')),  
    13.                          ' ',  
    14.                          substring-before($sentence, ' '))  
    15.              else $sentence"/>  
    16. </xsl:function>  
    17.   
    18. <xsl:template match="/">  
    19. <output>  
    20.   <xsl:value-of select="str:reverse('DOG BITES MAN')"/>  
    21. </output>  
    22. </xsl:template>  
    23.   
    24. </xsl:transform>  
    <xsl:transform 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:str="http://example.com/namespace"
      version="2.0"
      exclude-result-prefixes="str">
    
    <xsl:function name="str:reverse" as="xs:string">
      <xsl:param name="sentence" as="xs:string"/>
      <xsl:sequence  
         select="if (contains($sentence, ' '))
                 then concat(str:reverse(substring-after($sentence, ' ')),
                             ' ',
                             substring-before($sentence, ' '))
                 else $sentence"/>
    </xsl:function>
    
    <xsl:template match="/">
    <output>
      <xsl:value-of select="str:reverse('DOG BITES MAN')"/>
    </output>
    </xsl:template>
    
    </xsl:transform>
    

    An alternative way of writing the same function is to implement the conditional logic at the XSLT level, thus:

    1. <xsl:function name="str:reverse" as="xs:string">  
    2.   <xsl:param name="sentence" as="xs:string"/>  
    3.   <xsl:choose>  
    4.     <xsl:when test="contains($sentence, ' ')">    
    5.       <xsl:sequence select="concat(str:reverse(substring-after($sentence, ' ')),  
    6.                                 ' ',  
    7.                                 substring-before($sentence, ' '))"/>  
    8.     </xsl:when>  
    9.     <xsl:otherwise>  
    10.       <xsl:sequence select="$sentence"/>  
    11.     </xsl:otherwise>  
    12.   </xsl:choose>  
    13. </xsl:function>   
    <xsl:function name="str:reverse" as="xs:string">
      <xsl:param name="sentence" as="xs:string"/>
      <xsl:choose>
        <xsl:when test="contains($sentence, ' ')">  
          <xsl:sequence select="concat(str:reverse(substring-after($sentence, ' ')),
                                    ' ',
                                    substring-before($sentence, ' '))"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:sequence select="$sentence"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:function> 

    Final Result Trees

    <!-- Category: instruction -->
    <xsl:result-document
      format? = { qname }
      href? = { uri-reference }
      validation? = "strict" | "lax" | "preserve" | "strip"
      type? = qname
      method? = { "xml" | "html" | "xhtml" | "text" | qname-but-not-ncname }
      byte-order-mark? = { "yes" | "no" }
      cdata-section-elements? = { qnames }
      doctype-public? = { string }
      doctype-system? = { string }
      encoding? = { string }
      escape-uri-attributes? = { "yes" | "no" }
      include-content-type? = { "yes" | "no" }
      indent? = { "yes" | "no" }
      media-type? = { string }
      normalization-form? = { "NFC" | "NFD" | "NFKC" | "NFKD" | "fully-normalized" | "none" |nmtoken }
      omit-xml-declaration? = { "yes" | "no" }
      standalone? = { "yes" | "no" | "omit" }
      undeclare-prefixes? = { "yes" | "no" }
      use-character-maps? = qnames
      output-version? = { nmtoken }>
      <!-- Content: sequence-constructor -->
    </xsl:result-document>

    属性解释:

    1:format:指定输出结果文档的格式,属性值是一个<output.../>元素的name属性值。

    2:href:指定输出结果文档的文件路径。

    Example: Multiple Result Documents

    The following example takes an XHTML document as input, and breaks it up so that the text following each <h1> element is included in a separate document. A new documenttoc.html is constructed to act as an index:

    1. <xsl:stylesheet  
    2.         version="2.0"  
    3.         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
    4.         xmlns:xhtml="http://www.w3.org/1999/xhtml">  
    5.           
    6. <xsl:output name="toc-format" method="xhtml" indent="yes"  
    7.             doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"  
    8.             doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"/>  
    9.               
    10. <xsl:output name="section-format" method="xhtml" indent="no"  
    11.             doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"  
    12.             doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"/>          
    13.            
    14. <xsl:template match="/">  
    15.   <xsl:result-document href="toc.html" format="toc-format" validation="strict">  
    16.     <html xmlns="http://www.w3.org/1999/xhtml">  
    17.       <head><title>Table of Contents</title></head>  
    18.       <body>  
    19.         <h1>Table of Contents</h1>  
    20.         <xsl:for-each select="/*/xhtml:body/(*[1] | xhtml:h1)">  
    21.           <p><href="section{position()}.html"><xsl:value-of select="."/></a></p>  
    22.         </xsl:for-each>  
    23.       </body>  
    24.     </html>  
    25.   </xsl:result-document>  
    26.   <xsl:for-each-group select="/*/xhtml:body/*" group-starting-with="xhtml:h1">  
    27.     <xsl:result-document href="section{position()}.html"   
    28.                          format="section-format" validation="strip">           
    29.       <html xmlns="http://www.w3.org/1999/xhtml">  
    30.         <head><title><xsl:value-of select="."/></title></head>  
    31.         <body>  
    32.           <xsl:copy-of select="current-group()"/>  
    33.         </body>  
    34.       </html>  
    35.     </xsl:result-document>  
    36.   </xsl:for-each-group>  
    37. </xsl:template>  
    38.   
    39. </xsl:stylesheet>   
    <xsl:stylesheet
            version="2.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:xhtml="http://www.w3.org/1999/xhtml">
            
    <xsl:output name="toc-format" method="xhtml" indent="yes"
                doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
                doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"/>
                
    <xsl:output name="section-format" method="xhtml" indent="no"
                doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
                doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"/>        
             
    <xsl:template match="/">
      <xsl:result-document href="toc.html" format="toc-format" validation="strict">
        <html xmlns="http://www.w3.org/1999/xhtml">
          <head><title>Table of Contents</title></head>
          <body>
            <h1>Table of Contents</h1>
            <xsl:for-each select="/*/xhtml:body/(*[1] | xhtml:h1)">
              <p><a href="section{position()}.html"><xsl:value-of select="."/></a></p>
            </xsl:for-each>
          </body>
        </html>
      </xsl:result-document>
      <xsl:for-each-group select="/*/xhtml:body/*" group-starting-with="xhtml:h1">
        <xsl:result-document href="section{position()}.html" 
                             format="section-format" validation="strip">         
          <html xmlns="http://www.w3.org/1999/xhtml">
            <head><title><xsl:value-of select="."/></title></head>
            <body>
              <xsl:copy-of select="current-group()"/>
            </body>
          </html>
        </xsl:result-document>
      </xsl:for-each-group>
    </xsl:template>
    
    </xsl:stylesheet> 

     

    字符映射

    <!-- Category: declaration -->
    <xsl:character-map
      name = qname
      use-character-maps? = qnames>
      <!-- Content: (xsl:output-character*) -->
    </xsl:character-map>

     

    属性解释:

    1:name:标识符;

    2:use-character-maps:用于包含另外一个字符映射。

     

    <xsl:output-character
      character = char
      string = string />

    属性解释:

    用character的属性值替代string的属性值。

    Example: Using Character Maps to Generate Non-XML Output

    Character maps can be useful when producing serialized output in a format that resembles, but is not strictly conformant to, HTML or XML. For example, when the output is a JSP page, there might be a need to generate the output:

    1. <jsp:setProperty name="user" property="id" value='<%= "id" + idValue %>'/>  
    <jsp:setProperty name="user" property="id" value='<%= "id" + idValue %>'/>


    Although this output is not well-formed XML or HTML, it is valid in Java Server Pages. This can be achieved by allocating three Unicode characters (which are not needed for any other purpose) to represent the strings<%,%>, and ", for example:

    1. <xsl:character-map name="jsp">  
    2.   <xsl:output-character character="«" string="<%"/>     
    3.   <xsl:output-character character="»" string="%>"/>  
    4.   <xsl:output-character character="§" string='"'/>  
    5. </xsl:character-map>  
    <xsl:character-map name="jsp">
      <xsl:output-character character="«" string="<%"/>   
      <xsl:output-character character="»" string="%>"/>
      <xsl:output-character character="§" string='"'/>
    </xsl:character-map>


    When this character map is referenced in the xsl:output declaration, the required output can be produced by writing the following in the stylesheet:

    1. <jsp:setProperty name="user" property="id" value='«= §id§ + idValue »'/>  
    <jsp:setProperty name="user" property="id" value='«= §id§ + idValue »'/>
    

    This works on the assumption that when an apostrophe or quotation mark is generated as part of an attribute value by the use of character maps, the serializer will (where possible) use the other choice of delimiter around the attribute value.

    数据类型绑定

    在<variable.../>、<param.../>和<with-param.../>元素中使用as属性,指定其数据类型,前面示例中用过。

    正则表达式

    <!-- Category: instruction -->
    <xsl:analyze-string
      select = expression
      regex = { string }
      flags? = { string }>
      <!-- Content: (xsl:matching-substring?, xsl:non-matching-substring?, xsl:fallback*) -->
    </xsl:analyze-string>

    <xsl:matching-substring>
      <!-- Content: sequence-constructor -->
    </xsl:matching-substring>

    <xsl:non-matching-substring>
      <!-- Content: sequence-constructor -->
    </xsl:non-matching-substring>

    呃!直接理解字面意思就可得意

    Example: Parsing a Date

    Problem: the input string contains a date such as 23 March 2002. Convert it to the form2002-03-23.

    Solution (with no error handling if the input format is incorrect):

    1. <xsl:variable name="months" select="'January', 'February', 'March', ..."/>  
    2.   
    3. <xsl:analyze-string select="normalize-space($input)"   
    4.     regex="([0-9]{{1,2}})s([A-Z][a-z]+)s([0-9]{{4}})">  
    5.     <xsl:matching-substring>  
    6.         <xsl:number value="regex-group(3)" format="0001"/>            
    7.         <xsl:text>-</xsl:text>  
    8.         <xsl:number value="index-of($months, regex-group(2))" format="01"/>  
    9.         <xsl:text>-</xsl:text>  
    10.         <xsl:number value="regex-group(1)" format="01"/>  
    11.     </xsl:matching-substring>  
    12. </xsl:analyze-string>  
    <xsl:variable name="months" select="'January', 'February', 'March', ..."/>
    
    <xsl:analyze-string select="normalize-space($input)" 
        regex="([0-9]{{1,2}})s([A-Z][a-z]+)s([0-9]{{4}})">
        <xsl:matching-substring>
            <xsl:number value="regex-group(3)" format="0001"/>          
            <xsl:text>-</xsl:text>
            <xsl:number value="index-of($months, regex-group(2))" format="01"/>
            <xsl:text>-</xsl:text>
            <xsl:number value="regex-group(1)" format="01"/>
        </xsl:matching-substring>
    </xsl:analyze-string>
    

    Note the use of normalize-space to simplify the work done by the regular expression, and the use of doubled curly brackets because theregex attribute is an attribute value template.

  • 相关阅读:
    设计模式学习——代理模式(Proxy Pattern)之 强制代理(强校验,防绕过)
    设计模式学习——代理模式(Proxy Pattern)
    设计模式学习——抽象工厂模式(Abstract Factory Pattern)
    最长字符串系列汇总
    窗口的最大值与最小值更新结构(滑动窗口)
    归并排序和归并排序应用(逆序对+小和)
    位运算在编程题的一些作用
    链表的排序(归并排序+快慢指针)
    Manacher算法解决最长回文子串长度问题
    回文数字的验证
  • 原文地址:https://www.cnblogs.com/qingzhou/p/4205614.html
Copyright © 2020-2023  润新知