2016-08-22 5 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> 

である私は私の入力のために、このXSLTを実行したときにそれは

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

<xsl:template match="/"> 

にマッチする他に一致する2 template.Oneを持っていますが、 XML、上のテンプレートのみが私のXMLに添付されています

<xsl:template match="/"> 

他の一致(_ソース/一致)は適用されません。同じXSLTで複数のテンプレートを使用できますか?私はここで何かを逃しているかもしれない。

答えて

3

もちろん、XMLにはmatch="/"テンプレートのみが適用されます。これはルートノードに一致し、他のテンプレートを呼び出すことはないため、他のテンプレートが呼び出されていないという事実は驚くべきことではありません。

より良い結果を得るには、<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> 

目的は、一つのことを行うテンプレートを重視しました。

ここに_source/extensionテンプレートを<xsl:apply-templates>を使用して正しい場所に呼び出してください。そのテンプレートから<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

関連する問題