1
votes

I'm new to XSLT and I'm not sure I am using the right wording for a node that I am creating in my template rather than one that is being processed. By 'current template node' I mean the a in this block:

<xsl:template match="item">
     <li>
         <a href="{location}">
             <xsl:value-of select="title" />
         </a>
     </li>
 </xsl:template>

I have another template match that I want to apply to the a:

<xsl:template match="a" mode="html">
    <a href="{@href}" title="this{@title}">
        <xsl:if test="number(substring(@href,1,4)='http')">
            <xsl:attribute name="class">external</xsl:attribute>
            <xsl:attribute name="target">_blank</xsl:attribute>
        </xsl:if>
        <xsl:value-of select="." />
    </a>
</xsl:template>

My question is: is it possible to apply this a template to the a I am creating in the item template or is matching like this only for context nodes? (also, for future searching, what do you call this kind of node?)

Thanks for reading.

Edit: in response to @Jim Garrison asking for my use-case, the example above is not far off. The only extra information I have to include is the node set I am working with, which looks like:

<related-links>
    <title>Link text</title>
    <location>http://link-address.whatever</location>
</related-links>

The a template I have is used to apply and 'external' class to every link placed in any node I am processing as HTML. I want to reuse it for this special related-links template. The only thing I can think to do currently is something like:

<xsl:template match="item">
     <li>
        <a href="{location}">
        <xsl:if test="number(substring(location,1,4)='http')">
            <xsl:attribute name="class">external</xsl:attribute>
            <xsl:attribute name="target">_blank</xsl:attribute>
        </xsl:if>
            <xsl:value-of select="title" />
        </a>
     </li>
 </xsl:template>

Which seems unnecessarily repetitious, especially considering this is the very beginning and I'm sure it will get more complicated. This can't be an uncommon thing to want to do... is there some other approach I should be using?

P.S. - I am using Symphony CMS which depends on libxslt so no XSLT 2.0

1

1 Answers

3
votes

Is it possible to apply this a template to the a I am creating in the item template ... ?

In XSLT 1.0 without extensions, no; matching is and can be performed only on input nodes.

In XSLT 1.0 with the (fairly common) node-set() extension, yes: assign the a element or its parent li element to a variable, construct a node set from that variable, and apply templates to the nodes in that node set.

In XSLT 2.0, yes: assign the a element or its parent li element to a variable, apply templates to the nodes in the value of that variable.

Note that saying "it is possible" is not the same as saying "it's a good idea". There may be other simpler and more direct ways of achieving what you want. In particular, if your immediate goal is to avoid duplicating link-related code in each of several places that generate links, you could use a named template (or in XSLT 2.0 also a user-defined function) to hold that code, and call that template (or function) from the places where it's needed. Any good book on XSLT (most serious XSLT programmers swear by Michael Kay's book, but I believe there are other good ones available) should be helpful getting a sense for how to use named templates and the xsl:call-template instruction, or user-defined functions.