XSLT:直接调用规则的应用模板,参数保持为空(Qt4 XSLT 处理器)

XSLT: apply-templates with directly invoked rule, param stays empty (Qt4 XSLT processor)

我试图通过具有直接 match 规则的 apply-templates 将一些变量向下发送到模板,但变量到达匹配模板时为空。我怀疑这是 Qt4 XSLT 处理器中缺少的功能或错误。

这是我的例子XML:

<Appointments>
  <Data>
    <Appointment StartDateTime="2017-11-20T13:00:00">
      <stay name="Hans Wu"/>
    </Appointment>
  </Data>
</Appointments>

这是 XSLT:

<xsl:stylesheet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xsl:template match="/">                
    <xsl:apply-templates select="/Appointments/Data/Appointment"/>
</xsl:template>

<xsl:template match="Appointment">
    <xsl:variable name="StartTime" select="@StartDateTime"/>
    <xsl:variable name="TestParam" select="'TestParam'"/>

    <div>
        <xsl:text>--- </xsl:text>
        <xsl:value-of select="$StartTime"/>
        <xsl:text> ---</xsl:text>
    </div>

    <xsl:apply-templates select="stay">
        <xsl:with-param name="StartTime" select="$StartTime"/>
        <xsl:with-param name="TestParam" select="$TestParam"/>
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="stay">
    <xsl:param name="StartTime"/>
    <xsl:param name="TestParam"/>

    <div>
        <xsl:text>### </xsl:text>
        <xsl:value-of select="$StartTime"/>
        <xsl:text> ###</xsl:text>
    </div>

    <div>
        <xsl:text>$$$ </xsl:text>
        <xsl:value-of select="$TestParam"/>
        <xsl:text> $$$</xsl:text>
    </div>

</xsl:template>

我希望生成的 HTML 也包含“###”文本中的时间戳,但是当我 运行 在我的 Qt4 环境中时,情况并非如此:

<div>--- 2017-11-20T13:00:00 ---</div>
<div>###  ###</div>
<div>$$$ TestParam $$$</div>

因为这在 oxygenDeveloper 中正如预期的那样工作并且应该是一个标准功能 - 这是一个错误吗? Qt4 的内置 XSLT 处理器中缺少?

Other similar answers suggested that the XSLT built-in template匹配,不会传参。由于我直接调用匹配的 "stay" 模板,如 "TestParam" 所示,我假设此问题中的问题不适用于此处。

看起来,这确实是 Qt4-XSLT 处理器的问题。

然而,一旦我停止在变量和参数的狭窄边界内思考并着眼于更大的图景,workaround/solution 就非常明显和简单。

这是适合我的 XSLT:

<xsl:template match="/">                
    <xsl:apply-templates select="/Appointments/Data/Appointment"/>
</xsl:template>

<xsl:template match="Appointment">
    <xsl:variable name="StartTime" select="@StartDateTime"/>
    <xsl:variable name="TestParam" select="'TestParam'"/>

    <div>
        <xsl:text>--- </xsl:text>
        <xsl:value-of select="$StartTime"/>
        <xsl:text> ---</xsl:text>
    </div>

    <xsl:apply-templates select="stay">
        <xsl:with-param name="TestParam" select="$TestParam"/>
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="stay">
    <xsl:param name="TestParam"/>

    <div>
        <xsl:text>### </xsl:text>
        <xsl:value-of select="../@StartDateTime"/>
        <xsl:text> ###</xsl:text>
    </div>

    <div>
        <xsl:text>$$$ </xsl:text>
        <xsl:value-of select="$TestParam"/>
        <xsl:text> $$$</xsl:text>
    </div>

</xsl:template>

这里的显着区别是 保留 -Template I select ../@StartDateTime 而不是 param 中的变量:

<xsl:value-of select="../@StartDateTime"/>

所以我 select 直接从父元素中获取 StartDateTime 属性,就这么简单。

适用于我的情况,如果你有一个更困难的结构,你 需要 使用变量,则可能不起作用。

xsl:apply-templates 将当前节点从 Appointment 更改为 stay。请改用 xsl:call-模板。

<xsl:stylesheet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml"/>
<xsl:template match="/">
    <root>
        <xsl:apply-templates select="/Appointments/Data/Appointment"/>
    </root>
</xsl:template>
<xsl:template match="Appointment">
    <xsl:variable name="StartTime" select="@StartDateTime"/>
    <xsl:variable name="TestParam" select="'TestParam'"/>
    <div>
        <xsl:text>--- </xsl:text>
        <xsl:value-of select="$StartTime"/>
        <xsl:text> ---</xsl:text>
    </div>
    <xsl:call-template name="stayHelper">
        <xsl:with-param name="StartTime" select="$StartTime"/>
        <xsl:with-param name="TestParam" select="$TestParam"/>
    </xsl:call-template>
</xsl:template>
<xsl:template name="stayHelper">
    <xsl:param name="StartTime"/>
    <xsl:param name="TestParam"/>
    <div>
        <xsl:text>### </xsl:text>
        <xsl:value-of select="$StartTime"/>
        <xsl:text> ###</xsl:text>
    </div>
    <div>
        <xsl:text>$$$ </xsl:text>
        <xsl:value-of select="$TestParam"/>
        <xsl:text> $$$</xsl:text>
    </div>
</xsl:template>
</xsl:stylesheet>