0

I have a xsl as below

<xsl:variable name="foo" select="concat('some','stuff')" />

<xsl:if test="$foo">
  <xsl:element name="hello">
    <xsl:attribute name="id">
        <xsl:value-of select="-1"/>
    </xsl:attribute>

        <xsl:element name="region">
            <xsl:value-of select="$foo/child"/>  <!-- foo is variable, but always has a 'child' node -->
        </xsl:element>

  </xsl:element>
</xsl:if>

I get the below output:

<hello id="-1">

and an exception:

java.lang.ClassCastException: org.apache.xpath.objects.XString incompatible with org.apache.xpath.objects.XNodeSet

what am I doing wrong?

3
  • I don't think the exception is coming from your XSL. Show the entire stack trace as well as your Java code, and clearly mark the line in the Java where the exception is thrown. These are fundamental requirements for asking questions about exceptions on StackOverflow. Commented Feb 5, 2014 at 19:05
  • I am able to get the <hello> node in the output, it fails at the exact line <xsl:value-of select="$foo/child"/> Commented Feb 5, 2014 at 19:08
  • Please provide a minimum reproducible example, which is: input XML and XSL. What Java says: $foo seems to be a string, not a node. But you can only select children from nodes, not from strings. Commented Feb 5, 2014 at 19:21

1 Answer 1

1
<xsl:variable name="foo" select="concat('some','stuff')" />

will create a string with value 'somestuff'.

The string turns your line

<xsl:value-of select="$foo/child"/> 

effectively into

<xsl:value-of select="'somestuff'/child"/> 

which is not a valid XPath expression.

Thie string cannot be used in any node expressions, only in string operations. Replace your

<xsl:variable name="foo" select="concat('some','stuff')" />

by something like

<xsl:variable name="foo" select="./somestuff" />

which returns a node.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, this was what I was looking for. Still a little confused though. Is there a way I can use ./ with `concat'?
No. concat will always create a string. If you really want to do that sort of thing, you'd need something like select="//*[local-name()=concat('some','stuff')]"/>, but I'd recommend finding an easier approach.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.