我是XSLT的新手,我有模板递归的麻烦. 我的问题是:我有两个文件xml,第一个是: EV forma codice="f01" ... forma codice="f02" ... forma ... /forma /forma /forma /EV 第二个是: forme !--codice_forma è "fxx"--fam
我的问题是:我有两个文件xml,第一个是:
<EV>
<forma codice="f01">
...
<forma codice="f02">
...
<forma>
...
</forma>
</forma>
</forma>
</EV>
第二个是:
<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>
现在我必须有这个trasform结果,加上属性“codice”:
<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>
非常感谢您的耐心和帮助!
最简单的样式表来做你需要的样子看起来像这样:<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>相同的结构.文档,你必须(好吧……应该)将样式表应用于该文档,而不是查找文档.
>“保持相同的结构”始终意味着从身份模板开始并根据需要覆盖它.
>在这种情况下,我们需要替换< forma>的所有codice属性.元素,所以我们只需要一个匹配forma / @ codice的模板并输出不同的属性.
> $forme [@codice = current()]选择匹配的< forma>从查找文档.
> $forma / @ figura | $forma /../@ tipo选择我们需要的两个属性节点.
>解决方案假设@codice数字在查找文档中是唯一的.
对于您的示例,输出如下所示:
<EV>
<forma tipo="quadrilatero" figura="rettangolo">
<!-- ... -->
<forma tipo="triangolo" figura="triangolo equilatero">
<!-- ... -->
<forma>
<!-- ... -->
</forma>
</forma>
</forma>
</EV>
