Selecting node sets (attributes or elements) which match a string variable name
xml, xpath, xslt
Solution
This selects an attribute with the name of `'foo'`.
<xsl:call-template name="print-value-of">
<xsl:with-param name="attribute-type" select="@*[name() = 'foo']"/>
</xsl:call-template>
<xsl:template name="print-value-of">
<xsl:param name="attribute-type"/>
<xsl:value-of select="."/>
</xsl:template>
Alternatively, you can leave the `<xsl:call-template>` like it is and do the change in your template:
<xsl:template name="print-value-of">
<xsl:param name="attribute-type"/>
<xsl:value-of select="@*[name() = $attribute-type]"/>
</xsl:template>
In any case, unless this was only a synthetic example, all of the above is a quite expensive way of saying:
<xsl:value-of select="@*[name() = $attribute-type]"/>
EDIT:
To create attributes with a dynamic name, use:
<xsl:attribute name="{$attribute-type}">
<xsl:value-of select="$some-value-or-expression" />
</xsl:attribute>
Note that the curly braces make the XSLT-processor evaluate their contents (in attribute values only).
You should make sure that `$attribute-type` contains a string that adheres to the XML naming rules. And you should think about renaming the variable to `$attribute-name`, because that's what it is.
Problem
Consider this simple xml element example: ``` <parent foo="1" bar="2" foobar="3"> <child/> </parent> ``` In the xsl file, I am in the context of "parent" (i.e. within the <template match="parent">). I want to select a node set (in the example, only one attribute) based upon a string variable. For example i want to select a node-set which matches $attribute-name. I'll show my failed xsl example and you will probably understand what i'm trying to do. ``` <xsl:template match="parent"> <xsl:call-template name="print-value-of"> <xsl:with-param name="attribute-type" select="'foo'"/> </xsl:call-template> </xsl:template> <xsl:template name="print-value-of"> <xsl:param name="attribute-type"/> <xsl:value-of select="$attribute-type"/> </xsl:template> ``` This prints the output: ``` foo ``` What I first INTENDED it to do (but I realize that this is not what it should do) is: - evaluate the variable attribute-type (or param, if you want to be picky) as the string 'foo' - call the value-of as if I had called <xsl:value-of select="foo"/> I.e. what I wanted it to print was: ``` 1 ``` THE QUESTION: How can I achieve this behaviour? Notice: I am aware of the fact that I, in this simple case, could pass the actual attribute node as a parameter (i.e. <xsl:with-param name="attribute" select="foo"/>). But that is not the solution I am searching for. I need to pass only information about the attribute type (or attribute name if you'd prefer to call it that) What I am actually trying to do is creating a general function template which can: - Call a function (call-template) with the attribute-type as a parameter - In the function do a bunch of operations which give me a node set, stored in a variable - sum all of the attributes of the elements in the node set, which are of the previously selected attribute-type <EDIT> I can only use XSLT 1.0, so 1.0 solutions are much preferred! </EDIT> <EDIT2> A follow-up question on a similar theme: Is it also possible to create attributes of a with the name/type specified by a string variable? I.e. ``` <xsl:attribute name="$attribute-type"/> ``` Doing it like the line above results in $attribute-type being the literal name of the attribute in the xml output. Instead I would like it, again it to evaluate the variable and give the evaluated value as the name. </EDIT2>