【问题标题】:How to apply a function to a sequence of nodes in XSLT如何将函数应用于 XSLT 中的节点序列
【发布时间】:2013-04-27 10:18:01
【问题描述】:

我需要编写一个将节点序列转换为字符串序列的 XSLT 函数。我需要做的是对序列中的所有节点应用一个函数,并返回一个与原始序列一样长的序列。

这是输入文档

<article id="4">
    <author ref="#Guy1"/>
    <author ref="#Guy2"/>
</article>

调用站点是这样的:

<xsl:template match="article">
    <xsl:text>Author for </xsl:text>
    <xsl:value-of select="@id"/>

    <xsl:variable name="names" select="func:author-names(.)"/>

    <xsl:value-of select="string-join($names, ' and ')"/>
    <xsl:value-of select="count($names)"/>
</xsl:function>

这是函数的代码:

<xsl:function name="func:authors-names">
    <xsl:param name="article"/>

    <!-- HELP: this is where I call `func:format-name` on
         each `$article/author` element -->
</xsl:function>

我应该在func:author-names 中使用什么?我尝试使用xsl:for-each,但结果是单个节点,而不是序列。

【问题讨论】:

  • 请添加所需输出的示例。
  • 令人困惑的是,在您想要“将函数应用于节点序列”的问题标题中,但是在您的代码中,您使用单个参数值调用函数节点。同样令人困惑的是,您没有指定参数的类型和函数的返回类型。这使得这个问题非常难以理解。我总是建议任何开始使用 XSLT 的人始终指定类型:变量、函数参数、模板参数和全局参数、模板输出的类型。

标签: xslt sequence xslt-2.0


【解决方案1】:

&lt;xsl:sequence select="$article/author/func:format-name(.)"/&gt;是一种方式,另一种是&lt;xsl:sequence select="for $a in $article/author return func:format-name($a)"/&gt;

我不确定你当然需要这个功能,做

<xsl:value-of select="author/func:format-name(.)" separator=" and "/>

article的模板中应该可以。

【讨论】:

  • 如果转换比简单的函数调用更复杂怎么办?
  • 我认为您关于“如何将函数应用于节点序列”的问题已得到解答。如果您在更复杂的内容和更复杂的输出方面需要更多帮助,最好提出一个新问题,该问题清楚地描述您对函数的输入类型和所需的函数结果类型。有一些方法可以将函数结果构造为函数体中的序列,以及与函数上的 as 属性交互,但很难在评论中详细说明。提出一个包含详细信息的新问题,我相信我们可以提供帮助。
【解决方案2】:

如果只需要生成一系列@ref 值,则不需要函数或xsl 2.0 版。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" />

    <xsl:template match="article">
        <xsl:apply-templates select="author" />
    </xsl:template>
    <xsl:template match="author">
        <xsl:value-of select="@ref"/>
        <xsl:if test="position() !=last()" >
            <xsl:text>,</xsl:text>
        </xsl:if>
    </xsl:template>
</xsl:styleshee

这将生成:

   #Guy1,#Guy2

更新: 请通过and 连接字符串并计算项目数。试试这个:

<xsl:template match="article">
    <xsl:text>Author for </xsl:text>
    <xsl:value-of select="@id"/>

    <xsl:apply-templates select="author" />

    <xsl:value-of select="count(authr[@ref])"/>
</xsl:template>
<xsl:template match="author">
    <xsl:value-of select="@ref"/>
    <xsl:if test="position() !=last()" >
        <xsl:text> and </xsl:text>
    </xsl:if>
</xsl:template>

有了这个输出:

  Author for 4#Guy1 and #Guy20

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多