简体   繁体   中英

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

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM