4

XSLT は初めてで、テンプレートの再帰に問題があります。私の問題は次のとおりです。2つのファイルxmlがあります。最初のものは次のとおりです。

    <EV>
        <forma codice="f01">
            ...
            <forma codice="f02">
                ...
                <forma>
                    ...
                </forma>
            </forma>
        </forma>
    </EV>

2番目は次のとおりです。

<forme> <!--codice_forma è "fxx"-->
<famiglia tipo="quadrilatero">
    <forma codice="f00" figura="quadrato"/>
    <forma codice="f01" figura="rettangolo"/>
</famiglia>
<famiglia tipo="triangolo">
    <forma codice="f02" figura="triangolo equilatero"/>
    <forma codice="f03" figura="triangolo rettangolo"/>
</famiglia>
</forme>

ここで、属性 "codice" で結合したこの trasform 結果が必要です。

<EV>
        <forma tipo="quadrilatero" figura="rettangolo">
           <forma ...>
               <forma ...>
                   ...
               </forma>
           </forma>
        </forma>
</EV>

XSLT ファイルに「forma」タグが含まれていません。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
    <evoluzione>
        <!-- Ciclo su tutti i possibili snapshot presenti -->
        <xsl:for-each select="/evoluzione/snapshot">
            <!-- Creo il tag snapshot -->
            <snapshot id="{@id}" label="{@label}">
                <!-- Creo il tag data -->
                <data giorno="{substring(@data,1,2)}" mese="{substring(@data,4,2)}" anno="{substring(@data,7,4)}"/>
                <!-- Ciclo su tutti i possibili esseri viventi presenti nello shapshot -->
                <xsl:for-each select="./EV">
                    <!-- Creo il tag EV -->
                    <EV cod_individuo="{@codice_individuo}" eta="{@eta}" salute="{@salute}" ciclo_di_vita="{@ciclo_di_vita}">
                        <!-- Invoco template sul file esseri_vienti.xml per ricavare l'aspettativa -->
                        <xsl:apply-templates select="document('/home/localhero/Scrivania/Progetto/esseri_viventi.xml')//EV">
                            <!-- Passo il parametro codInd al template -->
                            <xsl:with-param name="codInd" select="@codice_individuo"/>
                        </xsl:apply-templates>
                        <!-- Creo il tag specie -->
                        <specie>
                            <!-- Invoco template sul file tipi_esseri_viventi.xml -->
                            <xsl:apply-templates select="document('/home/localhero/Scrivania/Progetto/tipi_esseri_viventi.xml')//tipo">
                                <!-- Passo il parametro codTip al template -->
                                <xsl:with-param name="codTip" select="@codice_tipo"/>
                            </xsl:apply-templates>
                        </specie>
                        <!-- Creo il tag matrice -->
                        <matrice>
                            <!-- Qui andranno i tag di <affinità specie>%</affinità> -->
                        </matrice>
                        <!--THE TROUBLE IS THERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-->
                        <!-- Invoco template sul file forme.xml -->
                        <xsl:apply-templates select="document('/home/localhero/Scrivania/Progetto/forme.xml')//forma">
                            <!-- Passo il parametro codForm al template -->
                            <xsl:with-param name="codForm" select=".//forma/@codice"/>
                        </xsl:apply-templates>


                    </EV>
                </xsl:for-each>
            </snapshot>
        </xsl:for-each>
    </evoluzione>
</xsl:template>

<!-- Richiamo template su tutti i nodi EV del file esseri_viventi.xml-->
<xsl:template match="EV">
    <!-- Parametro codInd ricevuto in input dal template -->
    <xsl:param name="codInd"/>
    <!-- Se l'attributo Stringa non è NULL -->
    <xsl:if test="@Stringa != ''">
        <!-- Espressione regolare sull'attributo Stringa -->
        <xsl:analyze-string select="@Stringa" regex="(.*),(.*),(.*),(.*),(.*),(.*),(.*)">
            <xsl:matching-substring>
                <!-- Se il codice individuo coincide allora crea l'attributo aspettativa -->
                <xsl:if test="$codInd = regex-group(2)">
                    <xsl:attribute name="aspettativa">
                        <xsl:value-of select="regex-group(6)"/>
                    </xsl:attribute>
                </xsl:if>
            </xsl:matching-substring>
        </xsl:analyze-string>
    </xsl:if>
</xsl:template>

<!-- Richiamo template su tutti i nodi tipo del file esseri_viventi.xml-->
<xsl:template match="tipo">
    <!-- Parametro codTip ricevuto in input dal template -->
    <xsl:param name="codTip"/>
    <!-- Se il codice tipo coincide allora crea gli attributi -->
    <xsl:if test="$codTip = @codice">
        <xsl:attribute name="famiglia">
            <xsl:value-of select="../@nome"/>
        </xsl:attribute>
        <xsl:attribute name="nome_specie">
            <xsl:value-of select="@specie"/>
        </xsl:attribute>
    </xsl:if>
</xsl:template>

<!-- Richiamo template su tutti i nodi forma del file forme.xml-->
<xsl:template match="forma">
    <!-- Parametro codForm ricevuto in input dal template -->
    <xsl:param name="codForm"/>
    <!-- Se il codice forma coincide allora crea gli attributi -->
    <xsl:if test="$codForm = @codice">
        <!--<xsl:value-of select="$codForm"/><br/>-->
        <!-- Creo il tag forma -->
        <forma>
            <xsl:attribute name="tipo">
                <xsl:value-of select="../@tipo"/>
            </xsl:attribute>
            <xsl:attribute name="figura">
                <xsl:value-of select="@figura"/>
            </xsl:attribute>
            <!-- Ricorsione -->
            <xsl:apply-templates select="forma">
                <!-- Passo il parametro codForm al template -->
                <xsl:with-param name="codForm" select="document('/home/localhero/Scrivania/Progetto/evoluzione.xml')//forma/@codice"/>
            </xsl:apply-templates>
        </forma>
    </xsl:if>
</xsl:template>
</xsl:stylesheet>

私の結果:

   ...
   <EV>
        <forma tipo="quadrilatero" figura="rettangolo"></forma>
        <forma tipo="triangolo" figura="triangolo equilatero"></forma>
        <forma ...></forma>
        <forma ...></forma>
        ...
        <forma ...></forma>
    </EV>

再帰が機能しないのはなぜですか?この方法でタグ「forma」を再帰モードに含めないのはなぜですか。

<forma>
  <forma>
     ...
  </forma>
</forma>

ご理解とご協力をいただき、誠にありがとうございました。

4

1 に答える 1

3

必要なことを行うための最も単純なスタイルシートは次のようになります。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:variable name="forme" select="document('/path/to/forme.xml')//forma" />

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

  <xsl:template match="forma/@codice">
    <xsl:variable name="forma" select="$forme[@codice = current()]" />
    <xsl:copy-of select="$forma/@figura | $forma/../@tipo" />
  </xsl:template>
</xsl:stylesheet>

ノート

  • ドキュメントと同じ構造を出力したいので、ルックアップ ドキュメントではなく、そのドキュメントにスタイルシートを適用する<EV>必要があります (そうすべきです)。
  • 「同じ構造を維持する」とは、常に ID テンプレートから開始し、必要に応じてオーバーライドすることを意味します。
  • この場合、要素のすべてのcodice属性を置き換える必要があるため、異なる属性<forma>に一致して出力するテンプレートのみが必要です。forma/@codice
  • $forme[@codice = current()]<forma>検索ドキュメントから一致するものを選択します。
  • $forma/@figura | $forma/../@tipo必要な 2 つの属性ノードを選択します。
  • このソリューションでは、@codice番号が参照ドキュメント内で一意であることを前提としています。

サンプルの出力は次のようになります。

<EV>
    <forma tipo="quadrilatero" figura="rettangolo">
        <!-- ... -->
        <forma tipo="triangolo" figura="triangolo equilatero">
            <!-- ... -->
            <forma>
                <!-- ... -->
            </forma>
        </forma>
    </forma>
</EV>
于 2013-11-07T13:29:42.283 に答える