spinsch
spinsch

Reputation: 1415

XSL get element value by another element value

In my object there is an element "filter". The value on this element is the element from which I want to have the value of each child.

What did I do wrong?

Example

<object>
    <name>hello</name>
    <filter>height</filter>
    <childs>
        <child>
            <width>10</width>
            <height>20</height>
            <weight>30</weight>
        </child>
    </childs>
</object>

I have tried the following but cannot get the value (20) to be returned:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
    <xsl:output method="text" />
    <xsl:template match="/">

        <!-- filter element name -->
        <xsl:variable name="filter" select="object/filter" />

        <xsl:for-each select="childs/child">
            <!-- i want to return the value (20) -->
            <xsl:value-of select="*[local-name()=$filter]" />
        </xsl:for-each>

    </xsl:template>
</xsl:stylesheet>

Thank you very much for your time.

Upvotes: 0

Views: 689

Answers (3)

michael.hor257k
michael.hor257k

Reputation: 116959

XSLT has a built-in key mechanism for resolving cross-references. I strongly recommend using it:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:key name="elem-by-name" match="child/*" use="local-name()" />
    
<xsl:template match="/object">
    <xsl:value-of select="key('elem-by-name', filter)" />
</xsl:template>

</xsl:stylesheet>

Upvotes: 1

Yitzhak Khabinsky
Yitzhak Khabinsky

Reputation: 22157

Or even simpler.

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>

    <xsl:template match="/object">
        <!-- filter element name -->
        <xsl:variable name="filter" select="filter"/>

        <xsl:for-each select="childs/child">
            <!-- i want to return the value (20) -->
            <xsl:value-of select="*[local-name()=$filter]"/>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 1

zx485
zx485

Reputation: 29022

Your code had the wrong context nodes. Try the following:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
    <xsl:output method="text" />

    <xsl:template match="/">
        <xsl:variable name="filter" select="object/filter" />
        <xsl:for-each select="object/childs/child">
            <!-- i want to return the value (20) -->
            <xsl:value-of select="*[local-name()=$filter]" />
        </xsl:for-each>
    </xsl:template>
    
</xsl:stylesheet>

Its output is 20.

Upvotes: 1

Related Questions