0

I am trying to get the name of the next element name using a common Xpath and a generic XSL. But unable to get the name of the element.

Input 1:

<test>
 <userId>we</userId>
 <userId1>
 <testy:tool/>
 </userId1>
</test>

Input 2:

<test>
 <userId>we</userId>
 <userId1>
 <testy:hammer/>
 </userId1>
</test>

Xsl I am using:

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0"
    >
    <xsl:template match="operationName">

        <xsl:value-of select="local-name(/test/userId1)"/>
        <xsl:apply-templates select="local-name(/test/userId1)" mode="next"/>

    </xsl:template>

    <xsl:template match="testy" mode="next">
        <xsl:value-of select="(following::testy | descendant::testy)[1]"/>
    </xsl:template>

</xsl:stylesheet>

But this always displays the value of UserID. Can anyone point what am I doing wrong here?

Cheers!

Sammy
  • 121
  • 4
  • 12
  • Your question is not clear at all. First, your input is not valid XML. Then, there are no `operationName` or 'testy' in your input, so the XSLT is not doing anything. Finally, it's not clear what the expected output is. – michael.hor257k Jul 18 '16 at 16:26
  • The output I require is or based on the input XML. – Sammy Jul 18 '16 at 16:46
  • Well, the path to it is `/test/userId1/*`. – michael.hor257k Jul 18 '16 at 16:50
  • When @michael.hor257k says the input is not valid XML, I think he means it's not well-formed XML, because it uses namespace prefixes (like `testy:`) that are not declared. – LarsH Jul 18 '16 at 17:44
  • @Sammy, you mention wanting the name of the next element, but then sometimes you talk about the value, which is an entirely different thing. Can you confirm which it is that you want? – LarsH Jul 18 '16 at 17:46
  • It is the name of the element not the value. Updated the query. – Sammy Jul 18 '16 at 20:00

1 Answers1

2

Your XSLT, as presented, has no templates that match any of the input XML elements. So it ends up using the default template. In effect, this outputs the concatenation of all text values in the document, i.e. we.

I'm guessing that you want to output the name of the next (descendant, sibling or other) element, relative to the userId1 element. Some XSLT that is closer to what you appear to want is:

<xsl:stylesheet
    xmlns:testy="http://example.testy.com"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

    <xsl:template match="/">
        <xsl:apply-templates select="/test/userId1" mode="next"/>
    </xsl:template>

    <xsl:template match="userId1" mode="next">
        <xsl:value-of select="name((following::testy:* | descendant::testy:*)[1])"/>
    </xsl:template>

</xsl:stylesheet>

To make it work, you'll need to fix your input to be well-formed in regard to namespaces:

<test xmlns:testy="http://example.testy.com">
  <userId>we</userId>
  <userId1>
    <testy:tool/>
  </userId1>
</test>
Community
  • 1
  • 1
LarsH
  • 27,481
  • 8
  • 94
  • 152