How to apply a function to a sequence of nodes in XSLT

怎甘沉沦 提交于 2021-01-04 04:31:00

问题


I need to write an XSLT function that transforms a sequence of nodes into a sequence of strings. What I need to do is to apply a function to all the nodes in the sequence and return a sequence as long as the original one.

This is the input document

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

This is how the calling site:

<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>

And this is the code of the 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>

What should I use inside func:author-names? I tried using xsl:for-each but the result is a single node, not a sequence.


回答1:


<xsl:sequence select="$article/author/func:format-name(.)"/> is one way, the other is <xsl:sequence select="for $a in $article/author return func:format-name($a)"/>.

I am not sure you would need the function of course, doing

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

in the template of article should do.




回答2:


If only a sequence of @ref values should be generated there is no need for a function or xsl version 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

This will generate:

   #Guy1,#Guy2

Update: Do have the string join by and and have a count of items. Try this:

<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>

With this output:

  Author for 4#Guy1 and #Guy20


来源:https://stackoverflow.com/questions/16250886/how-to-apply-a-function-to-a-sequence-of-nodes-in-xslt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!