我是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>