Selecting node sets (attributes or elements) that match a string variable name
Consider this simple example of an XML element:
<parent foo="1" bar="2" foobar="3">
<child/>
</parent>
In the xsl file, I ended up in the "parent" context (ie, inside the parent <template match = "gt"). I want to select a set of node (in the example, just one attribute) based on a string variable. For example, I want to select a node-set that matches $ attribute-name. I'll show my bad xsl example and you can probably figure out 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>
Will print the output:
foo
What I first ASSIGNED to do this (but I realize this is not what it should be doing):
- evaluate an attribute type variable (or param if you want to be legible) as string 'foo'
- call the value as if I were calling <xsl: value-select = "foo" / ">
those. i wanted it to print:
1
QUESTION . How can I achieve this behavior?
Notification . I know that in this simple case, I could have passed the actual node attribute as a parameter (eg <xsl: with-param name = "attribute" select = "foo" />). But this is not the solution I am looking for. I only need to pass information about the type of the attribute (or the name of the attribute if you prefer to call it)
What I am actually trying to do is create a generic function template that can:
- Call a function (call pattern) with an attribute type as a parameter
- A bunch of operations are done in a function which gives me a set of node stored in a variable
- summarize all the attributes of the elements in the node set that are of the previously selected attribute type
<EDIT>
I can only use XSLT 1.0, so 1.0 is very preferred!
</EDIT>
<EDIT2>
Next question on a similar topic: Is it possible to also create a attributes with the name / type given by a string variable? I.e.
<xsl:attribute name="$attribute-type"/>
Doing it like the line above, the result in $ attribute-type is the literal name of the attribute in the xml output. Instead, I would like it to evaluate the variable again and give the evaluated value as a name.
</ EDIT2>
source to share
This selects the attribute named '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 <xsl:call-template>
it as it is and make changes to 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, if this is not just a synthetic example, all of the above is a rather expensive way:
<xsl:value-of select="@*[name() = $attribute-type]"/>
EDIT:
To create dynamically named attributes use:
<xsl:attribute name="{$attribute-type}">
<xsl:value-of select="$some-value-or-expression" />
</xsl:attribute>
Note that the curly braces force the XSLT processor to evaluate their content (in attribute values only).
You must make sure to $attribute-type
contain a string that adheres to the XML naming conventions. And you should consider renaming the variable to $attribute-name
, because that is what it is.
source to share