我是XSLT的新手,我在模板递归方面遇到了麻烦。 我的问题是:我有两个文件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>
非常感谢您的耐心和帮助!
答案 0 :(得分: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>
文档相同的结构,因此您必须(以及应)将样式表应用于 文档,不要查阅文件。codice
元素的所有<forma>
属性,因此我们只需要一个匹配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>