2011-06-28 75 views
0

我正在使用XSLT和XML,我的XML格式如下。如何在XSLT中使用帶有應用模板的鍵

<?xml version="1.0"?> 
<offices> 
    <resources resource="/include/xml/system_ek.xml" /> 
    <office id="217065"> 
    <city code="ABJ">Abidjan</city> 
    <country code="CI">Cote D'Ivoire (Ivory Coast)</country> 
    <region code="AF">Africa</region> 
    <name>(Town office)</name> 
    <countryTelephone>+225 2 025 6250</countryTelephone> 
    <address> 
     1st Floor, Escalier E<br />Immeuble Jeceda, Boulevard de la Republique<br />Le Plateau, Abidjan 
    </address> 
    <telephone>+225 2 025 6250</telephone> 
    <fax>+225 2 025 6254</fax> 
    <email>[email protected]</email> 
    <officeHours>Mon to Fri, 08:00 to 16:00</officeHours> 
    <officeHours>Sat, 09:00 to 12:30</officeHours> 
    <officeHours>Sun, Closed</officeHours> 
    <description>test</description> 
    <isCollectionOffice /> 
    <isFulfilmentOffice /> 
    <latitude>5.325053</latitude> 
    <longitude>-4.019526</longitude> 
    </office> 
    <office id="217066"> 
    <city code="ACC">Accra</city> 
    <country code="GH">Ghana</country> 
    <region code="AF">Africa</region> 
    <name>(Town office)</name> 
    <countryTelephone>+233 2 121 3131</countryTelephone> 
    <RefundRequestEmail>[email protected]</RefundRequestEmail> 
    <EmailReplyToAddress>[email protected]</EmailReplyToAddress> 
    <FareQuoteEnquiryEmail>[email protected]</FareQuoteEnquiryEmail> 
    <address> 
     Ground floor, Meridian House<br />Ring Road Central, Accra 
    </address> 
    <telephone>+233 2 121 3131</telephone> 
    <fax>+233 2 121 3158</fax> 
    <email>[email protected]</email> 
    <officeHours>Mon to Fri, 09:45 to 17:00</officeHours> 
    <officeHours>Sat, 09:00 to 13:00</officeHours> 
    <officeHours>Sun, Closed</officeHours> 
    <description>test</description> 
    <isCollectionOffice /> 
    <isFulfilmentOffice /> 
    <latitude>5.573179</latitude> 
    <longitude>-0.202158</longitude> 
    </office> 
    <office id="217067"> 
    <city code="ADD">Addis Ababa</city> 
    <country code="ET">Ethiopia</country> 
    <region code="AF">Africa</region> 
    <name>test (Airport office)</name> 
    <countryTelephone>+251 11 518 1818</countryTelephone> 
    <address> 
     Bole International Terminal 
     <br /> 
     Office number - 2B 
     <br /> 
     Addis Ababa 
    </address> 
    <telephone>+251 11 665 0434/35/06</telephone> 
    <fax>+251 11 665 0437</fax> 
    <email>[email protected]</email> 
    <officeHours>Daily, 09:00 to 21:00</officeHours> 
    <description>Airport Office</description> 
    <isCollectionOffice /> 
    <latitude>8.982919</latitude> 
    <longitude>38.796329</longitude> 
    </office> 
</offices> 

我有以下XSLT,它使用分頁爲好,要求是它應產生的三列(「地方辦事處」 ----「城市」 -----「國家」)在此之下所有的細節都是一樣的。這裏是XSLT,當我試圖列表時,我只是被稱爲模板「Office」。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:tlink="urn:TridionLinking" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:utils="urn:XSLTExtensions" exclude-result-prefixes="xsl xlink tlink msxsl utils"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" omit-xml-declaration="yes" /> 

    <!-- Translations are still loaded here because of XHTML content, research a way around that --> 
    <xsl:key name="kOfficeByID" match="office" use="@id"/> 
    <xsl:variable name="offices" select="/offices"/> 
    <xsl:param name="publicationPath"/> 
    <xsl:param name="pubURL"/> 
    <xsl:param name="pageURL"/> 
    <xsl:param name="country"/> 
    <xsl:param name="city"/> 
    <xsl:param name="sortby"/> 
    <xsl:param name="order"/> 


    <!-- Current date to determine articles to show based on published/unpublished dates --> 
    <xsl:param name="currentDate"/> 

    <!-- offset controls the starting position of the results to show --> 
    <xsl:param name="offset">0</xsl:param> 
    <!-- blockSize controls how many results to show on a single page --> 
    <xsl:param name="blockSize" select="5" /> 

    <!-- Amount of page links to show by default --> 
    <xsl:param name="pagesShown">15</xsl:param> 

    <xsl:variable name="totalHits" > 
    <xsl:choose> 
     <xsl:when test="$city='' and $country=''"> 
     <xsl:value-of select="count(/offices/office)" /> 
     </xsl:when> 
     <xsl:when test="$country!=''"> 
     <xsl:value-of select="count(/offices/office/country)" /> 
     </xsl:when> 
     <xsl:when test="$city!=''"> 
     <xsl:value-of select="count(/offices/office/city)" /> 
     </xsl:when> 
    </xsl:choose> 
    </xsl:variable> 

    <xsl:template name="calcStart"> 
    <xsl:choose> 
     <xsl:when test="$offset = 0">1</xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="($offset * $blockSize) + 1"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

    <xsl:template name="calcEnd"> 
    <xsl:choose> 
     <xsl:when test="(($offset + 1) * $blockSize) > $totalHits"> 
     <xsl:value-of select="$totalHits"/> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="($offset + 1) * $blockSize"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

    <xsl:template name="pageNavigation"> 
    <xsl:param name="pageCount"/> 
    <xsl:param name="currPage"/> 
    <xsl:param name="showPages"> 
     <xsl:choose> 
     <xsl:when test="$pagesShown > $pageCount"> 
      <xsl:value-of select="$pageCount"/> 
     </xsl:when> 
     <xsl:when test="($pagesShown mod 2) = 0"> 
      <xsl:value-of select="$pagesShown"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$pagesShown + 1"/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:param> 
    <xsl:param name="currEntry" select="1"/> 
    <xsl:param name="offset"> 
     <xsl:choose> 
     <xsl:when test="($currPage &lt; $showPages) or ($pageCount = 1)">0</xsl:when> 
     <xsl:when test="$currPage > ($pageCount - $showPages + 1)"> 
      <xsl:value-of select="$pageCount - $showPages"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$currPage - ($showPages div 2) - 1"/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:param> 

    <!-- Header Processing --> 
    <xsl:if test="$currEntry = 1"> 
     <xsl:if test="($pageCount > $showPages) and ($currPage >= $showPages)"> 
     <li>... </li> 
     </xsl:if> 
    </xsl:if> 

    <xsl:if test="not ($currEntry > $showPages)"> 
     <li> 
     <xsl:choose> 
      <xsl:when test="($currEntry + $offset) = $currPage"> 
      <strong class="thisPage"> 
       <xsl:value-of select="$currEntry + $offset"/> 
      </strong> 
      </xsl:when> 
      <xsl:otherwise> 
      <a href="{concat($pageURL,'?offset=',$currEntry + $offset - 1,'&amp;r=',$city,'&amp;c=',$country,'&amp;sortby=',$sortby,'&amp;order=',$order)}"> 
       <xsl:value-of select="$currEntry + $offset"/> 
      </a> 
      </xsl:otherwise> 
     </xsl:choose> 
     </li> 

     <xsl:if test="not ($currEntry >= $showPages)"> 
     <li class="separatorLine">|</li> 
     </xsl:if> 

     <xsl:call-template name="pageNavigation"> 
     <xsl:with-param name="pageCount" select="$pageCount"/> 
     <xsl:with-param name="currPage" select="$currPage"/> 
     <xsl:with-param name="showPages" select="$showPages"/> 
     <xsl:with-param name="currEntry" select="$currEntry + 1"/> 
     <xsl:with-param name="offset" select="$offset"/> 
     </xsl:call-template> 
    </xsl:if> 

    <!-- Footer Processing --> 
    <xsl:if test="$currEntry = 1"> 
     <xsl:if test="($pageCount > $showPages) and (($pageCount - $currPage + 1) >= $showPages)"> 
     <li> ...</li> 
     </xsl:if> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template name="displayPageNavigation"> 
    <div class="continueBarPagination"> 
     <div class="continueBarLeft"> 
     <xsl:variable name="displayStart"> 
      <xsl:call-template name="calcStart"/> 
     </xsl:variable> 
     <xsl:variable name="displayEnd"> 
      <xsl:call-template name="calcEnd"/> 
     </xsl:variable> 
     <strong> 
      <xsl:value-of select="concat($displayStart, '-', $displayEnd)"/> 
     </strong> 
     </div> 
     <div class="continueBarRight"> 
     <ul class="paginationLinks"> 
      <!-- Show a back button when available --> 
      <xsl:choose> 
      <xsl:when test="$offset > 0"> 
       <li class="noBorder first"> 
       <a class="iconButtonBackBar" href="{$pageURL}?offset={$offset - 1}&amp;r={$country}&amp;c={$city}&amp;sortby={$sortby}&amp;order={$order}"> 
        <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text> 
       </a> 
       </li> 
      </xsl:when> 
      <xsl:otherwise> 
       <li class="noBorder first"> 
       <span class="iconButtonBackBarOff"> 
        <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text> 
       </span> 
       </li> 
      </xsl:otherwise> 
      </xsl:choose> 

      <!-- Output the page navigation links --> 
      <xsl:call-template name="pageNavigation"> 
      <xsl:with-param name="pageCount"> 
       <xsl:choose> 
       <xsl:when test="$blockSize >= $totalHits">1</xsl:when> 
       <xsl:when test="($totalHits mod $blockSize) != 0"> 
        <xsl:value-of select="ceiling($totalHits div $blockSize)"/> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:value-of select="$totalHits div $blockSize"/> 
       </xsl:otherwise> 
       </xsl:choose> 
      </xsl:with-param> 
      <xsl:with-param name="currPage" select="$offset + 1"/> 
      </xsl:call-template> 

      <!-- Show a next button when available --> 
      <xsl:choose> 
      <xsl:when test="(($offset + 1) * $blockSize) >= $totalHits"> 
       <li class="last"> 
       <span class="iconButtonForwardBarOff"> 
        <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text> 
       </span> 
       </li> 
      </xsl:when> 
      <xsl:otherwise> 
       <li class="last"> 
       <a class="iconButtonForwardBar" href="{$pageURL}?offset={$offset + 1}&amp;r={$country}&amp;c={$city}&amp;sortby={$sortby}&amp;order={$order}"> 
        <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text> 
       </a> 
       </li> 
      </xsl:otherwise> 
      </xsl:choose> 
     </ul> 
     </div> 
     <div class="clearBoth"> 
     <xsl:comment/> 
     </div> 
    </div> 
    <div class="spacer20"> 
     <xsl:comment/> 
    </div> 
    </xsl:template> 

    <!-- root match --> 
    <xsl:template match="/offices"> 
    <xsl:variable name="LinkUrl" select="concat($pageURL,'?offset=',$offset,'&amp;r=',$country,'&amp;c=',$city)"/> 
    <input type="hidden" id="hdRegion" name="hdRegion" value="{$country}" /> 
    <div class="brownBarContainer"> 
     <div class="brownBar"> 
     <xsl:text>Local Offices</xsl:text> 
     </div> 
    </div> 
    <table width="100%" cellspacing="0" cellpadding="0" border="0" class="displayTable"> 
     <tbody> 
     <tr> 
      <th scope="col"> 
      <xsl:choose> 
       <xsl:when test="$sortby='d' or $sortby=''"> 
       <xsl:attribute name="class">first sortSelected</xsl:attribute> 
       </xsl:when> 
       <xsl:otherwise> 
       <xsl:attribute name="class">first sortHover</xsl:attribute> 
       </xsl:otherwise> 
      </xsl:choose> 
      <div class="thPadding"> 
       <xsl:element name="a"> 
       <xsl:choose> 
        <xsl:when test="($sortby='d' or $sortby='') and ($order='asc' or $order='')"> 
        <xsl:attribute name="class">iconDownSortArrow</xsl:attribute> 
        <xsl:attribute name="href"> 
         <xsl:value-of select="concat($LinkUrl,'&amp;sortby=d','&amp;order=desc')" /> 
        </xsl:attribute> 
        </xsl:when> 
        <xsl:when test="($sortby='d' or $sortby='') and ($order='desc' or $order='')"> 
        <xsl:attribute name="class">iconUpSortArrow</xsl:attribute> 
        <xsl:attribute name="href"> 
         <xsl:value-of select="concat($LinkUrl,'&amp;sortby=d','&amp;order=asc')" /> 
        </xsl:attribute> 
        </xsl:when> 
        <xsl:otherwise> 
        <xsl:attribute name="class">iconSortArrowOff</xsl:attribute> 
        <xsl:attribute name="href"> 
         <xsl:value-of select="concat($LinkUrl,'&amp;sortby=d','&amp;order=asc')" /> 
        </xsl:attribute> 
        </xsl:otherwise> 
       </xsl:choose> 
       </xsl:element> 
       <xsl:text>Local Offices</xsl:text> 
      </div> 
      </th> 
      <th scope="col"> 
      <xsl:choose> 
       <xsl:when test="$sortby='r'"> 
       <xsl:attribute name="class">sortSelected</xsl:attribute> 
       </xsl:when> 
       <xsl:otherwise> 
       <xsl:attribute name="class">sortHover</xsl:attribute> 
       </xsl:otherwise> 
      </xsl:choose> 
      <div class="thPadding"> 
       <xsl:element name="a"> 
       <xsl:choose> 
        <xsl:when test="($sortby='r') and ($order='asc' or $order='')"> 
        <xsl:attribute name="class">iconDownSortArrow</xsl:attribute> 
        <xsl:attribute name="href"> 
         <xsl:value-of select="concat($LinkUrl,'&amp;sortby=r','&amp;order=desc')" /> 
        </xsl:attribute> 
        </xsl:when> 
        <xsl:when test="($sortby='r') and ($order='desc' or $order='')"> 
        <xsl:attribute name="class">iconUpSortArrow</xsl:attribute> 
        <xsl:attribute name="href"> 
         <xsl:value-of select="concat($LinkUrl,'&amp;sortby=r','&amp;order=asc')" /> 
        </xsl:attribute> 
        </xsl:when> 
        <xsl:otherwise> 
        <xsl:attribute name="class">iconSortArrowOff</xsl:attribute> 
        <xsl:attribute name="href"> 
         <xsl:value-of select="concat($LinkUrl,'&amp;sortby=r','&amp;order=asc')" /> 
        </xsl:attribute> 
        </xsl:otherwise> 
       </xsl:choose> 
       </xsl:element> 
       <xsl:text>City</xsl:text> 
      </div> 
      </th> 
      <th scope="col"> 
      <xsl:choose> 
       <xsl:when test="$sortby='c'"> 
       <xsl:attribute name="class">sortSelected</xsl:attribute> 
       </xsl:when> 
       <xsl:otherwise> 
       <xsl:attribute name="class">sortHover</xsl:attribute> 
       </xsl:otherwise> 
      </xsl:choose> 
      <div class="thPadding"> 
       <xsl:element name="a"> 
       <xsl:choose> 
        <xsl:when test="($sortby='c') and ($order='asc' or $order='')"> 
        <xsl:attribute name="class">iconDownSortArrow</xsl:attribute> 
        <xsl:attribute name="href"> 
         <xsl:value-of select="concat($LinkUrl,'&amp;sortby=c','&amp;order=desc')" /> 
        </xsl:attribute> 
        </xsl:when> 
        <xsl:when test="($sortby='c') and ($order='desc' or $order='')"> 
        <xsl:attribute name="class">iconUpSortArrow</xsl:attribute> 
        <xsl:attribute name="href"> 
         <xsl:value-of select="concat($LinkUrl,'&amp;sortby=c','&amp;order=asc')" /> 
        </xsl:attribute> 
        </xsl:when> 
        <xsl:otherwise> 
        <xsl:attribute name="class">iconSortArrowOff</xsl:attribute> 
        <xsl:attribute name="href"> 
         <xsl:value-of select="concat($LinkUrl,'&amp;sortby=c','&amp;order=asc')" /> 
        </xsl:attribute> 
        </xsl:otherwise> 
       </xsl:choose> 
       </xsl:element> 
       <xsl:text>Country</xsl:text> 
      </div> 
      </th> 
     </tr> 
     <xsl:variable name="sortorder"> 
      <xsl:choose> 
      <xsl:when test="$order='asc' or $order=''">ascending</xsl:when> 
      <xsl:otherwise>descending</xsl:otherwise> 
      </xsl:choose> 
     </xsl:variable> 
     <xsl:choose> 
      <xsl:when test="$city='' and $country=''"> 
      <xsl:choose> 
       <xsl:when test="$sortby='d' or $sortby=''"> 
       <xsl:apply-templates select="office[@id]"> 
        <xsl:sort select="$offices/office/name/." order="{$sortorder}" /> 
       </xsl:apply-templates>   
       </xsl:when> 
       <xsl:when test="$sortby='r' or $sortby=''"> 
       <xsl:apply-templates select="office[@id]"> 
        <xsl:sort select="$offices/office/city/." order="{$sortorder}" /> 
       </xsl:apply-templates> 
       </xsl:when> 
       <xsl:when test="$sortby='c' or $sortby=''"> 
       <xsl:apply-templates select="office[@id]">     
        <xsl:sort select="$offices/office/country/." order="{$sortorder}" /> 
       </xsl:apply-templates> 
       </xsl:when> 
      </xsl:choose> 
      </xsl:when> 
     </xsl:choose>   
     </tbody> 
    </table> 
    <div class="horRuleWhite"> 
     <hr/> 
    </div> 
    <xsl:call-template name="displayPageNavigation" /> 
    </xsl:template> 

    <xsl:template match="office"> 
    <xsl:if test="(position() >= ($offset * $blockSize) + 1) and (position() &lt;= ($offset + 1) * $blockSize)"> 
     <xsl:variable name="cityId" select="@id"/> 
     <xsl:variable name="url" select="$offices/destination[city/@id=$cityId]/@url"/> 
     <xsl:variable name="vReverseURL"> 
     <xsl:call-template name="reverse"> 
      <xsl:with-param name="string" select="$url"/> 
     </xsl:call-template> 
     </xsl:variable> 
     <xsl:variable name="vCountryURL"> 
     <xsl:call-template name="reverse"> 
      <xsl:with-param name="string" select="substring-after(substring-after($vReverseURL,'/'),'/')"/> 
     </xsl:call-template> 
     <xsl:text>/index.aspx</xsl:text> 
     </xsl:variable> 
     <xsl:variable name="vRegionURL"> 
     <xsl:call-template name="reverse"> 
      <xsl:with-param name="string" select="substring-after(substring-after(substring-after($vReverseURL,'/'),'/'),'/')"/> 
     </xsl:call-template> 
     <xsl:text>/index.aspx</xsl:text> 
     </xsl:variable> 
     <xsl:variable name="title"> 
     <xsl:choose> 
      <xsl:when test="@title"> 
      <xsl:value-of select="@title"/> 
      </xsl:when> 
      <xsl:otherwise> 
      <xsl:value-of select="$offices/office/name/." /> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:variable> 
     <tr> 
     <td class="detail first"> 
      <a class="arrowSmallFront"> 
      <xsl:value-of select="$title"/> 
      </a> 
     </td> 
     <td class="detail noLeftBorder"> 
      <a class="arrowSmallFront" href="{concat($pubURL, $vCountryURL)}"> 
      <xsl:value-of select="$offices/office/city/."/> 
      </a> 
     </td> 
     <td class="detail noLeftBorder"> 
      <a class="arrowSmallFront" href="{concat($pubURL, $vRegionURL)}"> 
      <xsl:value-of select="$offices/office/country/."/> 
      </a> 
     </td> 
     </tr> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template name="reverse"> 
    <xsl:param name="string" select="''"/> 
    <xsl:if test="$string != ''"> 
     <xsl:call-template name="reverse"> 
     <xsl:with-param name="string" select="substring($string,2)"/> 
     </xsl:call-template> 
     <xsl:value-of select="substring($string,1,1)"/> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

在上面的XSLT我有一個模板,通過名稱的xsl:模板匹配=「辦公室」,如果你看到有我使用「密鑰」。在下面我從上面的XSLT中獲取的代碼中,我嘗試使用apply-templates,但它不起作用,不要考慮分頁,我會照顧。

<xsl:when test="$city='' and $country=''"> 
      <xsl:choose> 
       <xsl:when test="$sortby='d' or $sortby=''"> 
       <xsl:apply-templates select="office[@id]"> 
        <xsl:sort select="$offices/office/name/." order="{$sortorder}" /> 
       </xsl:apply-templates>   
       </xsl:when> 
       <xsl:when test="$sortby='r' or $sortby=''"> 
       <xsl:apply-templates select="office[@id]"> 
        <xsl:sort select="$offices/office/city/." order="{$sortorder}" /> 
       </xsl:apply-templates> 
       </xsl:when> 
       <xsl:when test="$sortby='c' or $sortby=''"> 
       <xsl:apply-templates select="office[@id]">     
        <xsl:sort select="$offices/office/country/." order="{$sortorder}" /> 
       </xsl:apply-templates> 
       </xsl:when> 
      </xsl:choose> 
     </xsl:when> 
+0

它似乎沒有你正在使用'Key' ... –

+1

請簡化通過只顯示所需要的理解您的問題的最基本這個問題,也見[問]。 – Abel

回答

1

由於您所顯示的巨大代碼牆,我無法理解您的意圖。我可以解釋一下如何在正常情況下使用xsl:key來應用模板。

如果您使用的是像一個關鍵:

<xsl:key name="kOfficeByID" match="office" use="@id"/> 

你被他們的@id收集office節點。如果您想使用密鑰應用模板,請使用key()函數。

<xsl:apply-templates select="key('kOfficeByID',@id)"/> 

其中模板將被應用到所有的節點office與所指示的@id。另一種方法(用於衆所周知的Meunchian方法)是使用密鑰將模板應用於具有給定密鑰(即分組)的單個辦公室節點。這是通過使用來實現:

<xsl:apply-templates select="Office[ 
    generate-id() 
    = generate-id(key('kOfficeByID',@id)[1])]"/> 
+0

這個代碼怎麼樣

+0

取決於你想要達到的目標。您可以使用這種類型的代碼將模板應用於具有相同「@ id」的模板中的單個節點。但是這是不正確的。您應該使用'key('kOfficeByID',@ id)[1]'因爲'generate-id'接受單個節點而不是節點集。 –

+0

擴大了一點包括這樣的解釋的答案。 –