2015-01-05 31 views
1

我有一个XML文件看起来像下面是什么目的的<xsl:调用模板...>

- <select1> 
    - <sel_details> 
     <type>Primary Type</type> 
     <name>Some Name</name> 
     <id>ID Num</id> 
    <sel_details> 
    ..... 
    <select1> 

和XSL看起来像这样

<xsl:for-each select="//select1"> 
    <xsl:call-template name="sel_details" /> 
    <xsl:with-param name="xmlSection" select="sel_details" /> 
    </xsl:call-template> 
    <xsl:call-template name="....." /> 
    <xsl:with-param name="xmlSection" select="....." /> 
    </xsl:call-template> 
    .......... 
</xsl:for-each> 

<xsl:template name="sel_details"> 
    <xsl:param name="xmlSection" /> 
     <xsl:for-each select="xmlSection"> 
      <xsl:value-of select="./type" /> 
     </xsl:for-each> 
</xsl:template> 

是什么目的<xsl:call-template...>然后<xsl:template name...>

如果我只写3这样的线,我能得到相同的值:在一个普通的编程语言

<xsl:for-each select="//select1/sel_details"> 
    <xsl:value-of select="./type" /> 
</xsl:for-each> 

回答

1

什么是命名模板?

在XSLT样式表中,xsl:call-template

<xsl:call-template name="construct-header"/> 

意味着调用所谓命名模板 - 具有name属性的xsl:template元件:

<xsl:template name="construct-header"> 

作为相对于一个匹配输入节点的模板,因此具有match属性:

<xsl:template match="book"> 

由于命名模板从不匹配到输入节点,所以使用xsl:call-template显式调用它们是执行它们内部代码的唯一方法。一旦命名模板被调用,代码将被评估,不会改变上下文(broadly speaking, at least)。所以,一个非常合理的问题是

为什么在一般情况下使用命名模板?

命名模板用于

  • 实现在XSLT递归算法。一个众所周知的例子是mimicking the tokenize() function in XSLT 1.0,它需要一个递归的命名模板。
  • 重用几个地方的代码块以避免重复
  • 将样式表组织成有意义的部分。这也可以通过模块化您的代码到由主样式表包含或导入的几个样式表中。

使用您的具体情况

命名模板如果代码是为你展示真正的短,我看不出有什么理由在这里使用一个命名模板。在命名模板中没有递归处理。但是也许在发布之前大大缩短了它,或者在样式表的其他地方重新使用了已命名的模板。这两个都是保持命名模板的合理原因。 (如果您想在这个明确的指导,请出示一个完整的样式表。)

如果你决定代码降低到xsl:for-each,然后又摆脱./,因为它是多余的,而且,从经验上讲,我说,不应该在路径表达式前面是//

<xsl:for-each select="select1/sel_details"> 
    <xsl:value-of select="type" /> 
</xsl:for-each> 
+0

非常感谢MathiasMüller!你的解释非常清楚直接! –

+0

嗨Mathias,关于你提到的'在几个地方重复使用代码块以避免重复',并且我也阅读了你提供的链接(至少广义而言),这是一个很好的问题和答案。非常感谢!我也有同样的担忧:例如,我声明了模板名称A,并选择了显示在页面顶部的值。然后,在页面结尾处,模板A的值必须再次显示,我试着''它不像预期的那样工作!我收到一个错误:“无法将#STRING转换为NodeList”如何让它工作?请指导。谢谢! –

+0

@abcidd评论部分不是提出一个新的,无关的问题的地方。开始一个新的问题帖子来做到这一点。然后我很高兴回答 - 或者别人会。但是请确保从头开始包含以下信息:完整的输入XML文档,完整的XSLT样式表,错误描述和您希望拥有的XML输出。 –

0

想想命名的功能。 <xsl:call-template>是函数调用的直接类比。是否值得将某段代码移动到单独的函数中 - 这是编码风格,代码重复次数和其他“模糊”考虑的问题。在这个特定的情况下,作者可能希望确保每个部分都将被统一化。也许,在之前的文件修订中,函数的主体并不重要。

+0

非常感谢,user3159253!从你的话来说,我已经了解了更多关于XSL的知识。谢谢! –

1

代码看起来对我来说,就好像它是由人谁还没掌握XSLT的应用模板的成语。我想象一个更有经验的XSLT程序员可能会写这样的事情:

<xsl:template match="/"> 
    ... 
    <xsl:apply-templates select="//select1"/> 
    ... 
</xsl:template> 

<xsl:template match="select1"> 
    <xsl:apply-templates select="sel_details" /> 
    <xsl:apply-templates select="....." /> 
</xsl:template> 

<xsl:template match="sel_details"> 
    <xsl:value-of select="type" /> 
</xsl:template> 

样式表中的xsl:for-each和xsl:调用模板和xsl:选择是主要的控制结构一般建议程序员是谁对XSLT习语尚不熟悉。有经验的XSLT编码人员使用匹配模板和xsl:apply-templates。

+0

非常感谢Mike Kay!这是对的,我不是XSL的主人,是的,我不知道'匹配'!非常感谢您分享经验!不胜感激。 –