使用xsl变量来捕获调用模板的输出,为我返回空白

时间:2011-06-13 21:48:37

标签: xml xslt transform

我看过很多帖子都是这样做的,这让我觉得这是可能的,我只是做错了。我尽可能地简化了它,试图弄清楚为什么会发生这种情况:

继承我的xml(没什么好激动的):

<?xml version="1.0" encoding="UTF-8"?>
<REPORT>

</REPORT>

这是我的xsl:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:template match="REPORT">
      <xsl:variable name="tryThisTemplate">
        <xsl:call-template name="TRY_THIS"/>
      </xsl:variable>
      <TEST1>
        <xsl:call-template name="TRY_THIS"/>
      </TEST1>
      <TEST2>
        <xsl:value-of disable-output-escaping="yes" select="$tryThisTemplate" />
      </TEST2>
      <TEST3>
        <xsl:value-of select="$tryThisTemplate" />
      </TEST3>
    </xsl:template>

    <xsl:template name="TRY_THIS">
      <MY_NODE desc="my description" />
    </xsl:template>
</xsl:stylesheet>

这是我的结果:

<?xml version="1.0" encoding="utf-8"?>  
<TEST1>
  <MY_NODE desc="my description"/>
</TEST1>
<TEST2></TEST2>
<TEST3></TEST3>

这是我的问题: 为什么TEST2和TEST3不起作用。 $ tryThisTemplate变量似乎为空。我在这里误解了什么。我应该以不同的方式做这件事吗?

4 个答案:

答案 0 :(得分:16)

以下是执行此操作的正确方法(请注意,DOE不是必需的,应该避免使用):

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="REPORT">
    <xsl:variable name="tryThisTemplate">
        <xsl:call-template name="TRY_THIS"/>
    </xsl:variable>
    <TEST1>
        <xsl:call-template name="TRY_THIS"/>
    </TEST1>
    <TEST2>
        <xsl:copy-of select="$tryThisTemplate" />
    </TEST2>
    <TEST3>
        <xsl:copy-of select="$tryThisTemplate" />
    </TEST3>
 </xsl:template>

 <xsl:template name="TRY_THIS">
    <MY_NODE desc="my description" />
 </xsl:template>
</xsl:stylesheet>

将此转换应用于提供的XML文档

<REPORT>

</REPORT>

生成了想要的结果

<TEST1>
   <MY_NODE desc="my description"/>
</TEST1>
<TEST2>
   <MY_NODE desc="my description"/>
</TEST2>
<TEST3>
   <MY_NODE desc="my description"/>
</TEST3>

说明: <xsl:copy-of>个副本(如其名称所示)节点。 <xsl:value-of>输出其select属性中的任何内容的字符串值。元素的字符串值是其所有文本节点后代的串联(按文档顺序)。在您的情况下,元素没有文本节点后代,因此<xsl:value-of>不输出任何内容。

答案 1 :(得分:4)

是的,这里有一个误解。如果您尝试将$tryThisTemplate的结构复制到输出,则需要使用<xsl:copy-of>而不是<xsl:value-of><xsl:value-of>输出其select参数的字符串值,即其文本内容,在本例中为空字符串。

答案 2 :(得分:3)

  

$ tryThisTemplate变量显示为空白

变量不是空白,但是xsl:value-of你要求其中的文本节点。那是“空白”。

例如,尝试:

  <TEST3>
    <xsl:copy-of select="$tryThisTemplate" />
  </TEST3>

你会看到MY_NODE:)之间出现TEST3

答案 3 :(得分:0)

查看我的解决方案

这是我的模板(是可验证的内容)

<xsl:template name="author-name" match="string-name">
    <xsl:if test="fn[string-length(normalize-space()) > 0] or given-names[string-length(normalize-space()) > 0]">
        <xsl:apply-templates select="fn | given-names" mode="ascii"/>
    </xsl:if>
    <xsl:if test="sn[string-length(normalize-space()) > 0] or surname[string-length(normalize-space()) > 0]">
        <xsl:text> </xsl:text><xsl:apply-templates select="sn | surname" mode="ascii"/>
    </xsl:if>
    <xsl:if test="sn[string-length(normalize-space()) > 0] or suffix[string-length(normalize-space()) > 0]">
        <xsl:text> </xsl:text><xsl:apply-templates select="sn | suffix" mode="ascii"/>
    </xsl:if>
</xsl:template>

当我在任何其他模板中使用它时,我只需将其称为

<xsl:template match="string-name">
    <xsl:variable name="author">
        <xsl:call-template name="author-name"/> <!--here is the tricky part-->
    </xsl:variable>
    <span class="NLM_{name()}">
        <xsl:copy-of select="@id" />
        <xsl:value-of select="normalize-space($author)" />
    </span>   
</xsl:template>

希望这可以帮助你