title: XSLT - how to get the name value of a node?
body: <p>We have (perhaps unusually formatted) XML files that (very simplified) look like this:</p>
  
  <pre><code>&lt;Contacts&gt;
      &lt;Contact&gt;
          &lt;Private&gt;
              &lt;Name&gt;John Doe&lt;/Name&gt;
              &lt;Address&gt;Somewhere1&lt;/Address&gt;
              ...
          &lt;/Private&gt;
      &lt;/Contact&gt;
      &lt;Contact&gt;
          &lt;Business&gt;
              &lt;Name&gt;John Business&lt;/Name&gt;
              &lt;Address&gt;Somewhere2&lt;/Address&gt;
              &lt;BusinessAddress&gt;Somewhere3&lt;/BusinessAddress&gt;
              ...
          &lt;/Business&gt;
      &lt;/Contact&gt;
      ...
  &lt;/Contacts&gt;
  </code></pre>
  
  <p>In reality, we have several dozens of different types of "Contact" nodes with many more attributes, several of which however are common between all types...</p>
  
  <p>We currently use a stylesheet to format the XML file that repeats the formatting for all common attributes for each type of "Contact" node:</p>
  
  <pre><code>&lt;!-- ... loads of prologue code --&gt;
  &lt;xsl:for-each select="Contacts/Contact/."&gt;
      &lt;xsl:choose&gt;
      &lt;xsl:when test="Private"&gt;
          &lt;!--    code to format each and every attribute of the current 
                  "Contact" element, e.g.: --&gt;
          &lt;td class="header"&gt;Private Contact&lt;/td&gt;
          &lt;td class="detail"&gt;&lt;xsl:value-of select="./Name"/&gt;&lt;/td&gt;
          &lt;!--   ...  --&gt;
      &lt;/xsl:when&gt;
  
      &lt;xsl:when test="Business"&gt;
          &lt;!--    code to format each and every attribute of the current 
                  "Contact" element, e.g.: --&gt;
          &lt;td class="header"&gt;Business Contact/&lt;td&gt;
          &lt;td class="detail"&gt;&lt;xsl:value-of select="./Name"/&gt;&lt;/td&gt;
          &lt;!--   ...  --&gt;
      &lt;/xsl:when&gt;
  
      &lt;!--   ...  --&gt;
  
      &lt;/xsl:choose&gt;
  &lt;/xsl:for-each&gt;
  </code></pre>
  
  <p>But we're getting more and more <code>&lt;Contact&gt;</code> types with more and more attributes, resulting in a mile-long stylesheet, so I want to simplify the stylesheet as follows:</p>
  
  <pre><code>&lt;!-- ... loads of prologue code --&gt;
  &lt;xsl:for-each select="Contacts/Contact/."&gt;
      &lt;!-- loads of formatting stuff common to each "Contact" type, but with 
           some wording that's "Contact" type dependant, e.g. --&gt;
      &lt;td class="header"&gt;**????** Contact&lt;/td&gt;
      &lt;td class="detail"&gt;&lt;xsl:value-of select="./Name"/&gt;&lt;/td&gt;
      &lt;xsl:choose&gt;
      &lt;xsl:when **????** = "Private"&gt;
          &lt;xsl:variable name="contactWhen"&gt;off&lt;/xsl:variable&gt;
      &lt;/xsl:when&gt;
      &lt;xsl:when **????** = "Business"&gt;
          &lt;xsl:variable name="contactWhen"&gt;office&lt;/xsl:variable&gt;
      &lt;/xsl:when&gt;
      &lt;!-- ...  --&gt;
      &lt;/xsl:choose&gt;
       &lt;td class="header"&gt;Contact/&lt;td&gt;
       &lt;td class="detail"&gt;Only during $contactWhen hours&lt;/td&gt;
  
      &lt;xsl:choose&gt;
      &lt;xsl:when test="Private"&gt;
         &lt;!-- code to format attributes specific for the current "Contact" --&gt;
      &lt;/xsl:when&gt;
  
      &lt;xsl:when test="Business"&gt;
         &lt;!-- code to format attributes specific for the current "Contact" --&gt;
      &lt;/xsl:when&gt;
  
      &lt;!--    ...  --&gt;
  
      &lt;/xsl:choose&gt;
  &lt;/xsl:for-each&gt;
  </code></pre>
  
  <p>My excuses if there are any typo's or syntax errors in above code samples, but I'm not very intimate to XSLT syntax and most of above code was hand-crafted for the sake of the example...</p>
  
  <p>My problem is that I'm not able to get the name value of the node under <code>Contact</code>, in this example <code>Private</code> or <code>Business</code>. I've tried using all variations I could think of, both of <code>value-of select=</code> and of simply <code>select= (a.o. "", ".", "./."</code>, <code>Contacts/Contact</code>, <code>Contacts/Contact/.</code>, <code>[local-]name()</code> and even <code>Field[@name='.']</code>).</p>
  
  <p>Some attempts produce errors, some result in an empty string, some return the name of the parent node, i.e. <code>Contact</code>, and some return the values of all subordinate attributes (without attribute names though) as a single string... :-(</p>
  
  <p>What should I code for <code>**????**</code> to test for the name value of the current node, and eventually assign some variable(s) a value based on the results of this test?</p>
  
  <p>Thanks for any assistance,</p>
  
  <p>Juul</p>
  
  <p>Hi,</p>
  
  <p>Thanks for the valuable input and I'll definitely consider converting this and some other similar) stylesheet(s) to use templates, but for now I'm under pressure to deliver this project.</p>
  
  <p>I tried all 3 suggestions in the 'for-each' loop and just before the 'choose', but all 3 fail:</p>
  
  <pre><code>&lt;td class="content2" colspan="2"&gt;&lt;xsl:value-of select="ancestor::Record/child::*[1]name"/&gt;&lt;/td&gt;
  </code></pre>
  
  <p>fails with XML error: expected 'EOF' found 'name'</p>
  
  <pre><code>&lt;td class="content2" colspan="2"&gt;&lt;xsl:value-of select="name()"/&gt;&lt;/td&gt;
  </code></pre>
  
  <p>returns "Contact", not the name of the first child name</p>
  
  <pre><code>&lt;xsl:variable name="contactType"&gt;
  &lt;xsl:choose&gt;
      &lt;xsl:when test="Private"&gt;Private&lt;/xsl:when&gt;
      &lt;xsl:when test="Business"&gt;Business&lt;/xsl:when&gt;
  &lt;/xsl:choose&gt;
  &lt;td class="content2" colspan="2"&gt;&lt;xsl:value-of select="$contactType"/&gt;&lt;/td&gt;
  &lt;/xsl:variable&gt;
  </code></pre>
  
  <p>fails with XML error: reference to variable 'contactType' cannot be resolved. The variable may not be defined or it may not be in scope.</p>
  
  <p>Can this behaviour be caused by having these constructs in inline code instead of in a template.</p>
  
  <p>Please advise,</p>
  
  <p>Juul</p>