Attribute Value Templates

1. Curly brackets and AVTs
2. Using {AVT}'s, Attribute Value Templates
3. AVT with pass-through
4. for-each inside an attribute value template

1.

Curly brackets and AVTs

Mike Kay + David Carlisle

>  I want to say
> <xsl:value-of select="el1/*[position()={$i}]"/>
> 
    
Write <xsl:value-of select="el1/*[position()=$i]"/>
or <xsl:value-of select="el1/*[number($i)]"/>

You should never have curly brackets inside an XPath expression.

[Ednote:]

The magic of AVT's ?

An Attribute Value Template is: (in very simple English)

An expression inside curly brackets {}.

E.g.

<xsl:tempalte match ="x">
  <elem attrib="{some-value}">
etc.
some-value can be an xpath expression such as path/to/sought/element
or a variable.
As Mike says, we can't use it in <xsl:template match=" ..... ">
we can't use it in   <xsl:value-of select=" ....">
we can't use it in   <xsl:variable select=".....">

And nowhere else? To which David C replied:

No.

It can only be used in an attribute declared to be an "Attribute Value template" in the XSLT recommendation.

There is no other possible description, the list of which elements take AVT arguments and which don't is somewhat arbitrary. You just have to check in each case. But attributes (select, test etc) that take xpath expressions are never interpreted as AVT, as Michael said.

Tony Graham kindly adds,

The boxed element "prototypes" in the XSLT recommendation and the similar prototypes in Mulberry's XSLT and XPath Quick Reference (mulberrytech) use "{" and "}" around the attribute values that may include AVTs.

After all, it doesn't make sense to put an AVT in something that's already going to be evaluated as an expression.

2.

Using {AVT}'s, Attribute Value Templates

Jeni Tennison



> Can someone please explain why I need to use {} bracket in the href
> of xsl:results-document?

The href attribute can take a literal value. For example:

  <xsl:result-document href="index.html">
    ...
  </xsl:result-document>

tells the processor to associate the result document with the URI "index.html".

If you want to have the path to the result document you're creating be dependent on something you compute within the stylesheet then use the attribute value template:

  <xsl:result-document href="{$vFilePath}">
    ...
  </xsl:result-document>

The XPath expression within the {}s is evaluated and the string value is inserted into the attribute value. Then the attribute value is used as normal. So if $vFilePath had the value 'index.html', this would be exactly the same as using 'index.html' literally as above.

> I'm familiar with using {} as a shortcut for writing values into
> output attributes but I'm not sure why I can't do something like:
>
> <xsl:result-document href="string($vFilePath) ...

This means that the URI associated with the result document is, literally, "string($vFilePath)". That isn't a legal URI, which is why Saxon is objecting to it.

> Below are some examples of xsk:result-document which have confused
> me.
>         This works..
>
>         <xsl:template match="file">
>                 <xsl:variable 
>              name="vFileName" 
>                 select="concat( 'file:///'
>                      , @path , 
>                       $fileSep , 'test.xml' )"/>
>                 <xsl:result-document href="{$vFileName}"  >
>                         <x>output..</x>
>                 </xsl:result-document>
>         </xsl:template>

Here, the value of the $vFileName is used as the value of the href attribute. Since the value of $vFileName is a string which is a legal URI, this is fine.

>         This does not work.... Saxon says : 
>         The system identifier of the principal
>              output file is unknown..
>
>         <xsl:template match="file">
>                 <xsl:variable 
>           name="vFileName" 
>            select="concat( 'file:///'
>                      , @path , 
>                        $fileSep , 'test.xml' )"/>
>                 <xsl:result-document href="$vFileName"  >
>                         <x>output..</x>
>                 </xsl:result-document>
>         </xsl:template>

Here, the literal string "$vFileName" is used as the URI. That isn't a valid URI, so Saxon objects to it.

>         This works..
>
>         <xsl:template match="file">
>
>                 <xsl:result-document
>                      href="{'file:///'}{@path}{$fileSep}{'test.xml'}"  >
>                         <x>output..</x>
>                 </xsl:result-document>
>         </xsl:template>

Each XPath expression is evaluated and inserted in place. The result is a legal URI, so Saxon does not object. It would be exactly the same if you used:

  <xsl:result-document href="file:///{@path}{$fileSep}test.xml">
    ...
  </xsl:result-document>

There's no need to use {}s for literal strings.

Basically, if you put it in {}s it gets evaluated. If you don't, it gets treated as a literal string.

3.

AVT with pass-through

Tom Passin



How to quote "${abc}" so it will pass through without
evaluation?

>  I can't figure out how to specify "${abc}" in attribute 
> values in my template so it will just generate "${abc}" and will not 
> try to evaluate it.

Double the braces -

{{$abc}}

4.

for-each inside an attribute value template

Michael Kay




> I need to pass parameters in a URL like: <a 
> href="page.jsp?param1=x&param2=y" /> The number of parameters is 
> unknown.

In XPath 2.0 you could use an XPath expression in your AVT containing a for expression, something like

href="{string-join(for $x in //param return concat(keyword, '=', value),
'&amp;')}"

In 1.0, don't use AVTs, use xsl:attribute

<xsl:attribute name="href">
  <xsl:for-each>

  </xsl:for-each>
</xsl:attribute>