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):

  1. evaluate an attribute type variable (or param if you want to be legible) as string 'foo'
  2. 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:

  1. Call a function (call pattern) with an attribute type as a parameter
  2. A bunch of operations are done in a function which gives me a set of node stored in a variable
  3. 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>

+2


source to share


1 answer


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.

+3


source







All Articles