繁体   English   中英

用XSLT排序XML

[英]Xml sorting with xslt

我正在尝试使用XSLT对基于JobDate XML进行排序。

例如,使用给定的test.xml

<ROOT>
 <Employees>
     <EmployeName JobDate="1-jan-2015 to 1-jan-2016">
        <Name>A</Name>
     </EmployeName>
     <EmployeName1 JobDate="2-nov-2014 to 5-may-2015">
       <Name>B</Name>
     </EmployeName1>
  </Employees>
</Root>

XSLT代码:

    <xsl:for-each select="ROOT/Employees">
      <xsl:for-each select="*">
        <xsl:sort select="." order="descending"/>
         <xsl:if test="fn:exists(EmployeName1)">
         <fo:table>
            <fo:table-column column-width="30mm"/>
            <fo:table-column column-width="30mm"/>
            <fo:table-body start-indent="0pt">
               <xsl:for-each select="EmployeName1">
                <fo:table-row>
                  <fo:table-cell number-columns-spanned="8" padding="-1" display-align="center">                                                                            <fo:block-container overflow="hidden">                                                      <fo:block text-align="left">                                                                                <fo:inline color="black" font-family="Tondo Corp" font-size="9pt" font-weight="bold">                                                                           <xsl:text>EmployeName1 - </xsl:text>                                                        </fo:inline>                                <xsl:for-each select="@JobDate">                                        <altova:inline-container-substitute color="black" font-family="Tondo Corp" font-size="9pt">                                         <fo:inline>                                                 <xsl:value-of select="string(.)"/>                  </fo:inline>                                                            </altova:inline-container-substitute>                                                                   </xsl:for-each>         </fo:block>                                                             </fo:block-container>                                                                           </fo:table-cell>
                 </fo:table-row>
                 <fo:table-row>
                    <fo:table>
                       <fo:table-column column-width="30mm"/>
                      <fo:table-column column-width="30mm"/>
                      <fo:table-body start-indent="0pt">
                         <xsl:for-each select="Name">
                           <fo:table-row>
                             <fo:table-cell padding="0" display-align="center" altova:is-body-cell="true">                                                                                              <fo:block-container overflow="hidden"><fo:block text-align="left">                                          <xsl:for-each select="upper-case(Name)">                                                                                                                <altova:inline-container-substitute color="red" font-family="Tondo Corp" font-size="7pt" font-weight="bold" margin-bottom="0mm" margin-top="0mm" padding-bottom="0mm" padding-top="0mm">                                                            <xsl:choose>                                                                    <xsl:when test=". instance of element() or . instance of document-node()">                                                                              <xsl:apply-templates/>                                                  </xsl:when>         <xsl:otherwise>                                                 <xsl:value-of select="."/>                                                      </xsl:otherwise>                                                                </xsl:choose>                                                           </altova:inline-container-substitute>                                   </xsl:for-each>                                                 </fo:block></fo:block-container>                                    </fo:table-cell
                           </fo:table-row>
                         </xsl:for-each>
                      </fo:table>
                    </fo:table>
                 </fo:table-row>
               </xsl:for-each>
            </fo:table-body>
         </fo:table>
         </xsl:if>
         <xsl:if test="fn:exists(EmployeName)">
         <fo:table>
            <fo:table-column column-width="30mm"/>
            <fo:table-column column-width="30mm"/>
            <fo:table-body start-indent="0pt">
               <xsl:for-each select="EmployeName1">
                <fo:table-row>
                  <fo:table-cell number-columns-spanned="8" padding="-1" display-align="center">                                                                            <fo:block-container overflow="hidden">                                                  <fo:block text-align="left">                                                                                <fo:inline color="black" font-family="Tondo Corp" font-size="9pt" font-weight="bold">                                                                           <xsl:text>EmployeName - </xsl:text>                                                         </fo:inline>                                                                                                <xsl:for-each select="@JobDate">                                                <altova:inline-container-substitute color="black" font-family="Tondo Corp" font-size="9pt">                 <fo:inline>                                                                         <xsl:value-of select="string(.)"/>  </fo:inline>                                                                                    </altova:inline-container-substitute>                                                   </xsl:for-each>                             </fo:block>                                         
</fo:block-container>                       
</fo:table-cell>
                 </fo:table-row>
                 <fo:table-row>
                    <fo:table>
                       <fo:table-column column-width="30mm"/>
                      <fo:table-column column-width="30mm"/>
                      <fo:table-body start-indent="0pt">
                         <xsl:for-each select="Name">
                           <fo:table-row>
                             <fo:table-cell padding="0" display-align="center" altova:is-body-cell="true">                      
<fo:block-container overflow="hidden">                                      <fo:block text-align="left">                                            <xsl:for-each select="upper-case(Name)">                                    <altova:inline-container-substitute color="red" font-family="Tondo Corp" font-size="7pt" font-weight="bold" margin-bottom="0mm" margin-top="0mm" padding-bottom="0mm" padding-top="0mm">                                        <xsl:choose>                                                                        <xsl:when test=". instance of element() or . instance of document-node()">                                                                              <xsl:apply-templates/>                                                  
</xsl:when>     <xsl:otherwise>                                                                 <xsl:value-of select="."/>                                                      </xsl:otherwise>                                                                </xsl:choose>                                                           </altova:inline-container-substitute>                                   </xsl:for-each>                                                 
</fo:block>                                                 
</fo:block-container>                                       
</fo:table-cell
                           </fo:table-row>
                         </xsl:for-each>
                      </fo:table>
                    </fo:table>
                 </fo:table-row>
               </xsl:for-each>
            </fo:table-body>
         </fo:table>
         </xsl:if>
      </xsl:for-each>
    </xsl:for-each>

我需要帮助对此xml进行排序,在此先感谢。

要在XSLT 1.0中做到这一点,您将需要进行一些相当复杂的字符串操作,因为您需要首先按年份,然后按月份,然后按日期进行排序。 月份是最棘手的,因为您实际上需要按月份编号而不是名称进行排序。

这是一种您可以做到的方式

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:variable name="years" select="'jan-feb-mar-apr-may-jun-jul-aug-sep-oct-nov-dec'" />
    <xsl:template match="/">
        <table> 
        <xsl:for-each select="ROOT/Employees"> 
            <xsl:for-each select="*"> 
                <xsl:sort select="substring-after(substring-after(substring-before(@JobDate, ' '), '-'), '-')" order="ascending" data-type="number"/>
                <xsl:sort select="string-length(substring-before($years, lower-case(substring-before(substring-after(@JobDate, '-'), '-'))))" order="ascending" data-type="number"/>
                <xsl:sort select="substring-before(@JobDate, '-')" order="ascending" data-type="number"/>
                <row>
                    <cell><xsl:value-of select="Name" /></cell>
                    <cell><xsl:value-of select="@JobDate" /></cell>
                </row>
            </xsl:for-each> 
        </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>

当应用于此输入时...

<ROOT>
 <Employees>
     <EmployeName JobDate="1-nov-2014 to 1-jan-2016">
        <Name>B</Name>
     </EmployeName>
     <EmployeName1 JobDate="1-nov-2015 to 5-may-2016">
       <Name>C</Name>
     </EmployeName1>
     <EmployeName2 JobDate="2-aug-2014 to 5-may-2015">
       <Name>A</Name>
     </EmployeName2>
  </Employees>
</ROOT>

输出如下

<table>
   <row>
      <cell>A</cell>
      <cell>2-aug-2014 to 5-may-2015</cell>
   </row>
   <row>
      <cell>B</cell>
      <cell>1-nov-2014 to 1-jan-2016</cell>
   </row>
   <row>
      <cell>C</cell>
      <cell>1-nov-2015 to 5-may-2016</cell>
   </row>
</table>

请注意,这是假设月份总是小写

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM