我们有一个描述树结构的输入文档:
<?xml version="1.0"?>
<html>
<mas>
<row> <col>2</col><col>4</col> </row>
<row> <col>3</col> </row>
<row> <col></col> </row>
<row> <col>5</col><col>6</col> </row>
<row> <col></col> </row>
<row> <col></col> </row>
</mas>
</html>
我们想创建一个树。我们想要这样的输出文档:
<Transform id="b_1">
<Transform id="b_2">
<Transform id="b_3"/>
</Transform>
<Transform id="b_4">
<Transform id="b_5"/>
<Transform id="b_6"/>
</Transform>
</Transform>
我有XSLT样式表:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<xsl:template name="vetka">
<xsl:param name="row"/>
<xsl:for-each select="html/mas/*[$row]/*" >
<xsl:variable name="col" select="position()"/>
<xsl:variable name="num" select="//html/mas/*[$row]/*[$col]"/>
<Transform>
<xsl:attribute name="id"><xsl:value-of select="concat('b_',$num)"/></xsl:attribute>
<xsl:call-template name="vetka">
<xsl:with-param name="row" select="$num"/>
</xsl:call-template>
</Transform>
</xsl:for-each>
</xsl:template>
<xsl:template match="/">
<xsl:result-document href="str.txt">
<xsl:call-template name="vetka">
<xsl:with-param name="row" select='1'/>
</xsl:call-template>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
但是我们得到两个("b_2","b_4")。我认为,递归不是开始。为什么?
主要问题是这一行…
<xsl:for-each select="html/mas/*[$row]/*" >
这第一次有效,因为您位于文档元素/
上。但是当您递归地调用模板时,您现在位于col
元素上,并且这个xsl:for-each
将查找称为html
的子元素。所以,你应该把它改成:
<xsl:for-each select="/html/mas/*[$row]/*" />
同样,当递归调用模板时,需要将row
参数设置为一个数字。目前它是一个字符串(恰好包含一个数字的字符串)。
试试这个XSLT,我稍微简化了一下(因为您的num
变量实际上只是当前col
元素的值)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template name="vetka">
<xsl:param name="row"/>
<xsl:for-each select="//html/mas/*[$row]/*[. != '']" >
<xsl:variable name="num" select="."/>
<Transform id="{concat('b_',$num)}">
<xsl:call-template name="vetka">
<xsl:with-param name="row" select="number($num)"/>
</xsl:call-template>
</Transform>
</xsl:for-each>
</xsl:template>
<xsl:template match="/">
<xsl:call-template name="vetka">
<xsl:with-param name="row" select='1'/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>
这并不完全产生您想要的输出,但是我无法确定您的b_1
来自哪里。