2011-11-10 58 views
0

我遇到了xsl:templates和xsl:call-template标记的问题。也许这是一个缺乏理解,但这是我想要做的...使用xslt转换xml到csv文件

如果我有一个匹配“/ *”的模板,我需要从封闭模板中调用其他模板,需要其他文档上下文,这样做的最有效方法是什么?调用标题和正文模板时,这样我可以覆盖匹配-PARAM =“/ *”从封闭的模板,但是当我做这个输出得到弄糟:

<xsl:template match="/*"> 

<xsl:call-template name="header"> 
    <xsl:with-param name="headerContext" select="./[1]"/> 
</xsl:call-template> 

<xsl:call-template name="body"> 
    <xsl:with-param name="bodyContext" select="*/*/[1]"/> 
</xsl:call-template> 

<xsl:template> 

我使用XSL 。如果我将对“标题”模板的调用注释掉,正文模板正常工作,反之亦然,但是如上例所示,从主模板调用这两个模板会使其行为异常。标题和正文模板需要选择文档的不同部分,这就是为什么我选择使用w0th-param,但我认为它不工作。

我应该使用apply-templates吗?

+0

“使他们行为奇怪”以什么方式?另请注意,您选择的表达式在其最终位置步骤中缺少节点测试。 –

+0

无法从此信息中诊断问题;但是,是的,你最好使用apply-templates来处理这种事情。 –

回答

0

XSL被设计为基于事件。因此,通常,您需要使用模板匹配,而不是明确指定要处理的后代。

<!-- Identity Template will copy every node to the output. --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<!-- You listed ./[1] as your xpath, but you might want to add more information 
    to make it more specific. i.e. element names, not just * and position. --> 
<xsl:template match="/*/header"> 
    <someOutputHeader><xsl:apply-templates /></someOutputHeader> 
</xsl:template> 

<xsl:template match="/something/*/body"> 
    <newBody><xsl:apply-templates /></newBody> 
</xsl:template> 

此外,在谓词前指定nodeTest是一种很好的做法。因此,例如,不要写“./ [1]”,你可以在斜线后面指定*。 “./* [1]”你也不需要使用“./”。它由xpath暗示。所以真的,这是“* [1]”