2016-08-22 68 views
1

我試圖使用XML文件上的XSLT將其轉換爲另一個XML文件。 這是我的XSLT如何在同一個XSLT中使用具有不同匹配的多個模板

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:og="http://og.com" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:fn="http://www.w3.org/2005/xpath-functions" 
    exclude-result-prefixes="xs fn"> 
    <xsl:output method="xml" encoding="UTF-8" byte-order-mark="no" 
     indent="yes" /> 

<xsl:template match="@*|node()"> 
    <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy> 
</xsl:template> 

<xsl:template match="_source/extension"> 
    <xsl:for-each select="*"> 
     <xsl:element name="MT"> 
      <xsl:attribute name="N" select="name()"/> 
      <xsl:attribute name="V" select="."/> 
     </xsl:element> 
    </xsl:for-each> 
</xsl:template> 

    <xsl:template match="/"> 
     <GSP> 
      <xsl:attribute name="VER"> 
       <xsl:value-of select="3.2" /> 
      </xsl:attribute> 
      <xsl:for-each select="root"> 
       <TM> 
        <xsl:value-of select="(floor(took) div floor(1000))" /> 
       </TM> 

       <RES> 
        <M> 
         <xsl:value-of select="floor(hits/total)" /> 
        </M> 
        <xsl:for-each select="hits/hits"> 
         <xsl:variable name="var1_resultof_first" as="node()" 
          select="_source" /> 
         <R> 
          <xsl:attribute name="N"> 
          <xsl:number format="0" level="single" /> 
          </xsl:attribute> 
          <U> 
           <xsl:sequence 
            select="xs:string(xs:anyURI(fn:string($var1_resultof_first/U)))" /> 
          </U> 
          <UE> 
           <xsl:sequence 
            select="xs:string(xs:anyURI(fn:string($var1_resultof_first/UE)))" /> 
          </UE> 
          <UD> 
           <xsl:sequence 
            select="xs:string(xs:anyURI(fn:string($var1_resultof_first/UD)))" /> 
          </UD> 
          <T> 
           <xsl:sequence select="fn:string($var1_resultof_first/T)" /> 
          </T> 
          <Last-Modified> 
           <xsl:value-of select="substring-before(_source/submitTime,'T')" /> 
          </Last-Modified> 
          <S> 
           <xsl:for-each select="highlight/newContent"> 
            <xsl:sequence select="fn:string(.)" /> 
           </xsl:for-each> 
          </S> 

         </R> 
        </xsl:for-each> 
       </RES> 
      </xsl:for-each> 
     </GSP> 
    </xsl:template> 
</xsl:stylesheet> 

它有一個匹配

<xsl:template match="_source/extension"> 

和匹配

<xsl:template match="/"> 

但其他兩個template.One當我運行這個XSLT我輸入XML,只有上述模板正在應用於我的XML

<xsl:template match="/"> 

其他匹配(_source/match)不適用。我們可以在同一個XSLT中使用多個模板嗎?我可能會在這裏錯過一些東西。

回答

3

當然,只有match="/"模板應用於您的XML。它匹配根節點,從不調用任何其他模板,所以事實上,沒有其他模板被調用不應該是一個驚喜。

爲了獲得更好的效果,請從代碼中刪除每個<xsl:for-each>,並用<xsl:apply-templates>和相應的匹配模板替換它。 <xsl:for-each>有其用途,但它們都不會在您的用例中出現。

像這樣:

<xsl:template match="/"> 
    <GSP VER="3.2"> 
     <xsl:apply-templates match="root" /> 
    </GSP> 
<xsl:template> 

<xsl:template match="root"> 
    <TM> 
     <!-- floor(1000) is... 1000. Maybe you mean something else? --> 
     <xsl:value-of select="floor(took) div floor(1000)" /> 
    </TM> 
    <RES> 
     <M><xsl:value-of select="floor(hits/total)" /></M> 
     <xsl:apply-templates="hits/hits" /> 
    </RES> 
</xsl:template> 

<xsl:template match="hits/hits"> 
    <R> 
     <xsl:attribute name="N"> 
      <xsl:number format="0" level="single" /> 
     </xsl:attribute> 
     <!-- you could use select="_source/U,_source/UE,_source/UT" here, too --> 
     <xsl:apply-templates select="_source/U" mode="URI" /> 
     <xsl:apply-templates select="_source/UE" mode="URI" /> 
     <xsl:apply-templates select="_source/UD" mode="URI" /> 
     <T><xsl:value-of select="_source/T" /></T> 
     <Last-Modified> 
      <xsl:value-of select="substring-before(_source/submitTime,'T')" /> 
     </Last-Modified> 
     <xsl:apply-templates select="highlight/newContent" /> 
    </R> 
</xsl:template> 

<xsl:template match="*" mode="URI"> 
    <xsl:copy> 
     <xsl:value-of select="xs:anyURI(.)" /> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="highlight/newContent"> 
    <S><xsl:value-of select="." /></S> 
</xsl:template> 

目的爲短期,集中的是做一件事情的模板。

使用<xsl:apply-templates>在正確的地方打電話給您的_source/extension模板。也從該模板中刪除<xsl:for-each>

閱讀What are the differences between 'call-template' and 'apply-templates' in XSL?For loops vs. apply-templatesdifferences between for-each and templates in xsl?以及其他類似帖子,以獲取關於模板如何在XSLT中工作的更多細節。

+0

謝謝。我會看看這些鏈接。 – Rose

相關問題