Get the value of the current node
Asked Answered
K

2

10

I'm not overly familiar with the terminology, so I'm not even sure the title of the question is accurate but I shall try to explain best I can.

I have the below XML example.

<countries>
  <country name="Afghanistan" population="22664136" area="647500">
    <language percentage="11">Turkic</language>
    <language percentage="35">Pashtu</language>
    <language percentage="50">Afghan Persian</language>
  </country>
</countries>

I use XPath down to the language nodes (/countries/country/ and then a for-each for the languages).

<language percentage="11">Turkic</language>

Using XSLT how can I output the value of , in the above example "Turkic". I can't think of another way to phrase the question but its like I am at the node and don't know the syntax to grab the value of this node.

Thanks in advance

Kongo answered 4/8, 2014 at 7:41 Comment(0)
G
14

The xsl:value-of element and current() function should do the trick:

<xsl:value-of select="current()"/>

I don't know the exact structure of your template, but for instance the following one outputs the language names:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/countries">
    <xsl:for-each select="country">
      <xsl:value-of select="current()"/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
Gudrin answered 4/8, 2014 at 7:52 Comment(12)
Thanks a bunch! I didn't even know such a function existed. Are they not mentioned in the w3schools syntax guide at all or did I miss such functions? Thanks again.Kongo
You're welcome. Both can be found at w3schools: value-of and current().Gudrin
Note: it is not a good idea to use //, which means "node by that name at any depth" (descendent-or-self). Use match="/countries" and select="country" instead, which just selects the children, and not descendants at any depth. Using // is often considered "evil" because it can introduce many subtle bugs (from overlapping nodes) and has a performance penalty (it has to go over each and every node again, as opposed to just a subset).Bevbevan
Or simply: <xsl:value-of select="."/>Oeo
I understand that <xsl:value-of select="."/> is not best practice? Or at least I can remember reading that somewhere. Also I prefer "current()" because it improves code-readability over just a single "." Either way your way still works so have a +1Kongo
@Abel: Sure thing, thanks for pointing that out! The above template was just an example that results in the desired output. Anyways, I've edited the template with your suggestions.Gudrin
@Kongo Using . as a shortcut for current() is common practice. As you get more familiar with XSLT, this and other shortcuts (such as .. or @) will become very readable.Oeo
@michael.hor257k: let's add to that that . is not the same as current(). In select="foo[. = 'test']" vs select="foo[current() = 'test']", the dot will change its focus to each foo element, i.e. it changes inside the XPath expression, while current() retains its focus to the current context item outside the current XPath (i.e., the context item of the current xsl:template or xsl:for-each). A small, often subtle, but important difference.Bevbevan
@Bevbevan I never claimed they were the same. I try to restrict my comments to the context of the topic at hand.Oeo
@michael.hor257k: of course, you are right. I didn't mean to criticize you, I know you know your stuff, just wanted to emphasize a common misunderstanding about . and current(). Apologies if I came across too cross.Bevbevan
@Bevbevan None taken. I just want to stress again, for the benefit of OP: <xsl:value-of select="current()"/> and <xsl:value-of select="."/> are exactly the same thing - says so right in the spec: w3.org/TR/xslt/#misc-func -- It should also be noted that strictly speaking, . is not a shortcut for current(); The current() function is an XSLT function, while . is an XPath abbreviation for the context node, i.e. self::node(). It just so happens that when current() is used in an outermost expression, "the current node is always the same as the context node" (ibid).Oeo
@michael.hor257k: well said/summarized, that is exactly it ;)Bevbevan
S
0

I know this is old post, but if someone is still looking for answers to this or with minor extension to original question.

How to select the particular element value of a repeated element <language> based on the attribute in the element e.g. percentage with value '11'. If you're having challenge in getting the value (as mentioned in the question) i.e., <language percentage="11">Turkic</language>

get the tag language

whose percentage value is 11

then try below code:

<xsl:template match="/">
    <xsl:for-each select="/countries/country">                               
       <language>                                                           
          <xsl:value-of select="./language[@percentage='11']"/>              
       <language>                                                              
    </xsl:for-each>                                                     
 </xsl:template>

Output:

<language>Turkic<language>
Sessoms answered 26/11, 2020 at 1:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.