title: XLST to Transform an XML Dataset of Arbitrary Recursive Structure to an Organization Chart
body: <p><em><strong>I answered my own question, but would appreciate constructive feedback on how I could improve it for speed, clarity, or a more idiomatic solution. :)</em></strong></p>
  
  <p>Please skip to <strong><em>~EDIT~</em></strong> or read through to it if you'd like to understand the original context of my question.</p>
  
  <p>In a nutshell, I have an XML dataset that looks something like this:</p>
  
  <pre><code>&lt;org&gt; &lt;!-- Organization --&gt;
    &lt;dep&gt; &lt;!-- Department --&gt;
      &lt;nm&gt;Department&lt;/nm&gt; &lt;!-- Department Name --&gt;
      &lt;emps&gt; &lt;!-- Head Department Employees --&gt;
        &lt;emp&gt; &lt;!-- One of the Head Employees --&gt;
          &lt;!-- Some Data, ie., L Name, F Name, and etc. (Omitted) --&gt;
        &lt;/emp&gt;
        &lt;emp&gt;
           &lt;!-- Omitted --&gt;
        &lt;/emp&gt;
      &lt;/emps&gt;
      &lt;deps&gt; &lt;!-- So-called "Sub-Departments" --&gt;
        &lt;dep&gt;
          &lt;nm&gt;Sub Department&lt;/nm&gt;
          &lt;emps&gt;
            &lt;emp&gt;
              &lt;!-- Omitted --&gt;
            &lt;/emp&gt;
          &lt;/emps&gt;
        &lt;/dep&gt;
      &lt;/deps&gt;
    &lt;/dep&gt;
  &lt;/org&gt;
  </code></pre>
  
  <p>That's a very small sample, but the key take away is that a department can can any number of employees and any number of sub-departments.  Usually, such a data-set would be bottom heavy, having few people at the top (leaders), and more and more as you navigate further down into the sub-departments.  What I have been trying to do--with a semi-breakthrough just today, actually--is figure out how to transform that XML Dataset into a somewhat no-frills, HTML Organization Chart.</p>
  
  <p>What I originally came up with spat out nested div's with strategically placed "float: left;" and "clear: both;" styles, and looked something like this:</p>
  
  <pre><code>+-------------------------------------------------------+
  |                         Dep                           |
  | +------------------------+                            |
  | | +--------+ +---------+ |                            |
  | | |  Emp   | |   Emp   | |                            |
  | | +--------+ +---------+ |                            |
  | +------------------------+                            |
  | +---------------------------------------------------+ |
  | | +----------------------+ +----------------------+ | |
  | | |         Dep          | |          Dep         | | |  
  | | | +--------+ +-------+ | | +--------+ +-------+ | | |
  | | | |  Emp   | |  Emp  | | | |  Emp   | |  Emp  | | | |
  | | | +--------+ +-------+ | | +--------+ +-------+ | | |
  | | +----------------------+ +----------------------+ | |
  | +---------------------------------------------------+ |
  +-------------------------------------------------------+
  </code></pre>
  
  <p>Apologies for my crude ASCII art.</p>
  
  <p>I had wracked my brain trying to come up with an XSLT transform that could produce this, instead:</p>
  
  <pre><code>+-------------------------------------------------------+
  |                         Dep                           |
  |             +------------------------+                |
  |             | +--------+ +---------+ |                |
  |             | |  Emp   | |   Emp   | |                |
  |             | +--------+ +---------+ |                |
  |             +------------------------+                |
  | +---------------------------------------------------+ |
  | | +----------------------+ +----------------------+ | |
  | | |         Dep          | |          Dep         | | |  
  | | | +--------+ +-------+ | | +--------+ +-------+ | | |
  | | | |  Emp   | |  Emp  | | | |  Emp   | | Emp   | | | |
  | | | +--------+ +-------+ | | +--------+ +-------+ | | |
  | | +----------------------+ +----------------------+ | |
  | +---------------------------------------------------+ |
  +-------------------------------------------------------+
  </code></pre>
  
  <p>Can't really do that with floating div's, and while absolute positioning works, the only div's that have a fixed width are the employee div's, so I needed to somehow get the total width of all contained elements to properly size each department, departments, and employees div.  Today, I had the idea that all I'd need to do is get a count of all the bottom-most employees div's at each department div, since organization charts tend to fan out from top to bottom:</p>
  
  <pre><code>&lt;xsl:template match="dep"&gt;
    &lt;!-- Just assuming that dep's, deps's, and emps's have no margin, padding, or border
      for the sake of keeping this example simpler --&gt;
  
    &lt;xsl:variable name="emp_count"
      select="count(descendant::emp[parent::emps/parent::dep[count(child::deps)=0]])"/&gt;
  
    &lt;xsl:variable name="width" select="$emp_count * $emp_width"/&gt;
    &lt;xsl:variable name="mleft" select="$width div 2"/&gt;
  
    &lt;div style="position: absolute; left: 50%; width: {$width}px;
                margin-left: -{$mleft}px;"&gt;
      &lt;xsl:apply-templates/&gt;
    &lt;/div&gt;
  &lt;/xsl:template&gt;
  </code></pre>
  
  <p>In a nutshell, while the above omits much, it works, barring any typos I have.  But!  Here's the problem.  That ASSUMES that the organization follows the time-honored tradition of being bottom-heavy.  How do I transform a org document that should output something like this?</p>
  
  <pre><code>+---------------------------------------------------------------+
  |                             Dep                               |
  | +-----------------------------------------------------------+ |
  | | +--------+ +---------+ +--------+ +---------+ +---------+ | |
  | | |  Emp   | |   Emp   | |  Emp   | |   Emp   | |   Emp   | | |
  | | +--------+ +---------+ +--------+ +---------+ +---------+ | |
  | +-----------------------------------------------------------+ |
  |     +---------------------------------------------------+     |
  |     | +----------------------+ +----------------------+ |     |
  |     | |         Dep          | |          Dep         | |     |  
  |     | | +--------+ +-------+ | | +--------+ +-------+ | |     |
  |     | | |  Emp   | |  Emp  | | | |  Emp   | | Emp   | | |     |
  |     | | +--------+ +-------+ | | +--------+ +-------+ | |     |
  |     | +----------------------+ +----------------------+ |     |
  |     +---------------------------------------------------+     |
  +---------------------------------------------------------------+
  </code></pre>
  
  <p>Ah...  Nothing like a corner case to ruin what I initially thought would have solved the problem that wracked my brain all week.  In truth, that corner case might not ever emerge.  In truth, maybe instead of using div's, using nested table's might have been easier.</p>
  
  <p>But, now I'm here, and I'm wondering...</p>
  
  <p>How would one go about calculating the width of a top-level department div with this corner case in mind, also keeping in mind that this corner case could occur more than once and  arbitrarily deep within the hierarchy?</p>
  
  <p><em><strong>~EDIT~</em></strong></p>
  
  <p>I want to turn this XML Source Document:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  
  &lt;dep&gt;
    &lt;nm&gt;Dep&lt;/nm&gt;
  
    &lt;emp&gt;
      &lt;nm&gt;Emp&lt;/nm&gt;
    &lt;/emp&gt;
  
    &lt;emp&gt;
      &lt;nm&gt;Emp&lt;/nm&gt;
    &lt;/emp&gt;
  
    &lt;emp&gt;
      &lt;nm&gt;Emp&lt;/nm&gt;
    &lt;/emp&gt;
  
    &lt;dep&gt;
      &lt;nm&gt;Sub Dep 1&lt;/nm&gt;
  
      &lt;emp&gt;
        &lt;nm&gt;Emp&lt;/nm&gt;
      &lt;/emp&gt;
  
      &lt;emp&gt;
        &lt;nm&gt;Emp&lt;/nm&gt;
      &lt;/emp&gt;
  
      &lt;dep&gt;
        &lt;nm&gt;Sub Dep 1-1&lt;/nm&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
      &lt;/dep&gt;
  
      &lt;dep&gt;
        &lt;nm&gt;Sub Dep 1-2&lt;/nm&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
      &lt;/dep&gt;
    &lt;/dep&gt;
  
    &lt;dep&gt;
      &lt;nm&gt;Sub Dep 2&lt;/nm&gt;
  
      &lt;emp&gt;
        &lt;nm&gt;Emp&lt;/nm&gt;
      &lt;/emp&gt;
  
      &lt;emp&gt;
        &lt;nm&gt;Emp&lt;/nm&gt;
      &lt;/emp&gt;
  
      &lt;emp&gt;
        &lt;nm&gt;Emp&lt;/nm&gt;
      &lt;/emp&gt;
  
      &lt;emp&gt;
        &lt;nm&gt;Emp&lt;/nm&gt;
      &lt;/emp&gt;
  
      &lt;dep&gt;
        &lt;nm&gt;Sub Dep 2-1&lt;/nm&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
      &lt;/dep&gt;
  
      &lt;dep&gt;
        &lt;nm&gt;Sub Dep 2-2&lt;/nm&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
      &lt;/dep&gt;
    &lt;/dep&gt;
  
    &lt;dep&gt;
      &lt;nm&gt;Sub Dep 3&lt;/nm&gt;
  
      &lt;emp&gt;
        &lt;nm&gt;Emp&lt;/nm&gt;
      &lt;/emp&gt;
    &lt;/dep&gt;
  
    &lt;dep&gt;
      &lt;nm&gt;Sub Dep 4&lt;/nm&gt;
  
      &lt;emp&gt;
        &lt;nm&gt;Emp&lt;/nm&gt;
      &lt;/emp&gt;
  
      &lt;emp&gt;
        &lt;nm&gt;Emp&lt;/nm&gt;
      &lt;/emp&gt;
  
      &lt;dep&gt;
        &lt;nm&gt;Sub Dep 4-1&lt;/nm&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
  
        &lt;dep&gt;
          &lt;nm&gt;Sub Dep 4-1-1&lt;/nm&gt;
  
          &lt;emp&gt;
            &lt;nm&gt;Emp&lt;/nm&gt;
          &lt;/emp&gt;
  
          &lt;emp&gt;
            &lt;nm&gt;Emp&lt;/nm&gt;
          &lt;/emp&gt;
  
          &lt;emp&gt;
            &lt;nm&gt;Emp&lt;/nm&gt;
          &lt;/emp&gt;
  
          &lt;emp&gt;
            &lt;nm&gt;Emp&lt;/nm&gt;
          &lt;/emp&gt;
  
          &lt;dep&gt;
            &lt;nm&gt;Sub Dep 4-1-1-1&lt;/nm&gt;
  
            &lt;emp&gt;
              &lt;nm&gt;Emp&lt;/nm&gt;
            &lt;/emp&gt;
          &lt;/dep&gt;
  
          &lt;dep&gt;
            &lt;nm&gt;Sub Dep 4-1-1-2&lt;/nm&gt;
  
            &lt;emp&gt;
              &lt;nm&gt;Emp&lt;/nm&gt;
            &lt;/emp&gt;
          &lt;/dep&gt;
        &lt;/dep&gt;
      &lt;/dep&gt;
  
      &lt;dep&gt;
        &lt;nm&gt;Sub Dep 4-2&lt;/nm&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
      &lt;/dep&gt;
    &lt;/dep&gt;
  &lt;/dep&gt;
  </code></pre>
  
  <p>...into this XML Result Document:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  
  &lt;deps emps-wide="16"&gt;
    &lt;dep emps-wide="16"&gt;
      &lt;nm&gt;Dep&lt;/nm&gt;
  
      &lt;emps emps-wide="3"&gt;
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
  
        &lt;emp&gt;
          &lt;nm&gt;Emp&lt;/nm&gt;
        &lt;/emp&gt;
      &lt;/emps&gt;
  
      &lt;deps emps-wide="16"&gt;
        &lt;dep emps-wide="5"&gt;
          &lt;nm&gt;Sub Dep 1&lt;/nm&gt;
  
          &lt;emps emps-wide="2"&gt;
            &lt;emp&gt;
              &lt;nm&gt;Emp&lt;/nm&gt;
            &lt;/emp&gt;
  
            &lt;emp&gt;
              &lt;nm&gt;Emp&lt;/nm&gt;
            &lt;/emp&gt;
          &lt;/emps&gt;
  
          &lt;deps emps-wide="5"&gt;
            &lt;dep emps-wide="3"&gt;
              &lt;nm&gt;Sub Dep 1-1&lt;/nm&gt;
  
              &lt;emps emps-wide="3"&gt;
                &lt;emp&gt;
                  &lt;nm&gt;Emp&lt;/nm&gt;
                &lt;/emp&gt;
  
                &lt;emp&gt;
                  &lt;nm&gt;Emp&lt;/nm&gt;
                &lt;/emp&gt;
  
                &lt;emp&gt;
                  &lt;nm&gt;Emp&lt;/nm&gt;
                &lt;/emp&gt;
              &lt;/emps&gt;
  
              &lt;deps emps-wide="0"/&gt;
            &lt;/dep&gt;
  
            &lt;dep emps-wide="2"&gt;
              &lt;nm&gt;Sub Dep 1-2&lt;/nm&gt;
  
              &lt;emps emps-wide="2"&gt;
                &lt;emp&gt;
                  &lt;nm&gt;Emp&lt;/nm&gt;
                &lt;/emp&gt;
  
                &lt;emp&gt;
                  &lt;nm&gt;Emp&lt;/nm&gt;
                &lt;/emp&gt;
              &lt;/emps&gt;
  
              &lt;deps emps-wide="0"/&gt;
            &lt;/dep&gt;
          &lt;/deps&gt;
        &lt;/dep&gt;
  
        &lt;dep emps-wide="4"&gt;
          &lt;nm&gt;Sub Dep 2&lt;/nm&gt;
  
          &lt;emps emps-wide="4"&gt;
            &lt;emp&gt;
              &lt;nm&gt;Emp&lt;/nm&gt;
            &lt;/emp&gt;
  
            &lt;emp&gt;
              &lt;nm&gt;Emp&lt;/nm&gt;
            &lt;/emp&gt;
  
            &lt;emp&gt;
              &lt;nm&gt;Emp&lt;/nm&gt;
            &lt;/emp&gt;
  
            &lt;emp&gt;
              &lt;nm&gt;Emp&lt;/nm&gt;
            &lt;/emp&gt;
          &lt;/emps&gt;
  
          &lt;deps emps-wide="3"&gt;
            &lt;dep emps-wide="1"&gt;
              &lt;nm&gt;Sub Dep 2-1&lt;/nm&gt;
  
              &lt;emps emps-wide="1"&gt;
                &lt;emp&gt;
                  &lt;nm&gt;Emp&lt;/nm&gt;
                &lt;/emp&gt;
              &lt;/emps&gt;
  
              &lt;deps emps-wide="0"/&gt;
            &lt;/dep&gt;
  
            &lt;dep emps-wide="2"&gt;
              &lt;nm&gt;Sub Dep 2-2&lt;/nm&gt;
  
              &lt;emps emps-wide="2"&gt;
                &lt;emp&gt;
                  &lt;nm&gt;Emp&lt;/nm&gt;
                &lt;/emp&gt;
  
                &lt;emp&gt;
                  &lt;nm&gt;Emp&lt;/nm&gt;
                &lt;/emp&gt;
              &lt;/emps&gt;
  
              &lt;deps emps-wide="0"/&gt;
            &lt;/dep&gt;
          &lt;/deps&gt;
        &lt;/dep&gt;
  
        &lt;dep emps-wide="1"&gt;
          &lt;nm&gt;Sub Dep 3&lt;/nm&gt;
  
          &lt;emps emps-wide="1"&gt;
            &lt;emp&gt;
              &lt;nm&gt;Emp&lt;/nm&gt;
            &lt;/emp&gt;
          &lt;/emps&gt;
  
          &lt;deps emps-wide="0"/&gt;
        &lt;/dep&gt;
  
        &lt;dep emps-wide="6"&gt;
          &lt;nm&gt;Sub Dep 4&lt;/nm&gt;
  
          &lt;emps emps-wide="2"&gt;
            &lt;emp&gt;
              &lt;nm&gt;Emp&lt;/nm&gt;
            &lt;/emp&gt;
  
            &lt;emp&gt;
              &lt;nm&gt;Emp&lt;/nm&gt;
            &lt;/emp&gt;
          &lt;/emps&gt;
  
          &lt;deps emps-wide="6"&gt;
            &lt;dep emps-wide="4"&gt;
              &lt;nm&gt;Sub Dep 4-1&lt;/nm&gt;
  
              &lt;emps emps-wide="3"&gt;
                &lt;emp&gt;
                  &lt;nm&gt;Emp&lt;/nm&gt;
                &lt;/emp&gt;
  
                &lt;emp&gt;
                  &lt;nm&gt;Emp&lt;/nm&gt;
                &lt;/emp&gt;
  
                &lt;emp&gt;
                  &lt;nm&gt;Emp&lt;/nm&gt;
                &lt;/emp&gt;
              &lt;/emps&gt;
  
              &lt;deps emps-wide="4"&gt;
                &lt;dep emps-wide="4"&gt;
                  &lt;nm&gt;Sub Dep 4-1-1&lt;/nm&gt;
  
                  &lt;emps emps-wide="4"&gt;
                    &lt;emp&gt;
                      &lt;nm&gt;Emp&lt;/nm&gt;
                    &lt;/emp&gt;
  
                    &lt;emp&gt;
                      &lt;nm&gt;Emp&lt;/nm&gt;
                    &lt;/emp&gt;
  
                    &lt;emp&gt;
                      &lt;nm&gt;Emp&lt;/nm&gt;
                    &lt;/emp&gt;
  
                    &lt;emp&gt;
                      &lt;nm&gt;Emp&lt;/nm&gt;
                    &lt;/emp&gt;
                  &lt;/emps&gt;
  
                  &lt;deps emps-wide="2"&gt;
                    &lt;dep emps-wide="1"&gt;
                      &lt;nm&gt;Sub Dep 4-1-1-1&lt;/nm&gt;
  
                      &lt;emps emps-wide="1"&gt;
                        &lt;emp&gt;
                          &lt;nm&gt;Emp&lt;/nm&gt;
                        &lt;/emp&gt;
                      &lt;/emps&gt;
  
                      &lt;deps emps-wide="0"/&gt;
                    &lt;/dep&gt;
  
                    &lt;dep emps-wide="1"&gt;
                      &lt;nm&gt;Sub Dep 4-1-1-2&lt;/nm&gt;
  
                      &lt;emps emps-wide="1"&gt;
                        &lt;emp&gt;
                          &lt;nm&gt;Emp&lt;/nm&gt;
                        &lt;/emp&gt;
                      &lt;/emps&gt;
  
                      &lt;deps emps-wide="0"/&gt;
                    &lt;/dep&gt;
                  &lt;/deps&gt;
                &lt;/dep&gt;
              &lt;/deps&gt;
            &lt;/dep&gt;
  
            &lt;dep emps-wide="2"&gt;
              &lt;nm&gt;Sub Dep 4-2&lt;/nm&gt;
  
              &lt;emps emps-wide="2"&gt;
                &lt;emp&gt;
                  &lt;nm&gt;Emp&lt;/nm&gt;
                &lt;/emp&gt;
  
                &lt;emp&gt;
                  &lt;nm&gt;Emp&lt;/nm&gt;
                &lt;/emp&gt;
              &lt;/emps&gt;
  
              &lt;deps emps-wide="0"/&gt;
            &lt;/dep&gt;
          &lt;/deps&gt;
        &lt;/dep&gt;
      &lt;/deps&gt;
    &lt;/dep&gt;
  &lt;/deps&gt;
  </code></pre>
  
  <p>For the sake of completeness, here is the XLST Transformation I used to produce <em>most</em> of that XML Result Document:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  
  &lt;xsl:stylesheet version="1.0"
                  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  
    &lt;xsl:output method="xml" indent="yes"/&gt;
  
    &lt;xsl:template match="/"&gt;
      &lt;xsl:call-template name="recurse-deps"/&gt;
    &lt;/xsl:template&gt;
  
    &lt;xsl:template name="recurse-deps"&gt;
      &lt;deps emps-wide=""&gt;
        &lt;xsl:for-each select="dep"&gt;
  
            &lt;dep emps-wide=""&gt;
              &lt;nm&gt;&lt;xsl:value-of select="nm"/&gt;&lt;/nm&gt;
  
              &lt;emps emps-wide=""&gt;
                &lt;xsl:for-each select="emp"&gt;
  
                    &lt;emp&gt;
                      &lt;nm&gt;&lt;xsl:value-of select="nm"/&gt;&lt;/nm&gt;
                    &lt;/emp&gt;
  
                &lt;/xsl:for-each&gt;
              &lt;/emps&gt;
  
              &lt;xsl:call-template name="recurse-deps"/&gt;
            &lt;/dep&gt;
  
        &lt;/xsl:for-each&gt;
      &lt;/deps&gt;
    &lt;/xsl:template&gt;
  
  &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>Note that I have <em>generalized</em> my original question.  Let's not even care about how this will be <em>displayed</em> as an organization chart.  That really wasn't the problem for which I was seeking to learn to solve in XSLT.</p>
  
  <p>Also note that I had to edit the XML Result Document because I--obviously--do not quite know how to write the XSLT Stylesheet to produce what I want.  Otherwise, I would not be here asking questions.  :)</p>
  
  <p>Here is what I am finding so much difficulty trying to express in XSLT, and why I had to manually edit the XML Result Document after running that transformation:</p>
  
  <ol>
  <li><p>Assume every <em>emp</em> element is 1 unit wide, whatever that unit may be.  Let's call it an <em>inch</em>, just for the sake of being able to visualize it.</p></li>
  <li><p>Every <em>emps</em> element should be as wide as the number of <em>emp</em> elements in it.  (So, an <em>emps</em> element with three <em>emp</em> elements in it would be three inches wide.)</p></li>
  <li><p>Every <em>dep</em> element should be as wide as its <em>emps</em> element, or its <em>deps</em> element, whichever is the widest of the two.  (So, a <em>dep</em> element with a 3-inch-wide <em>emps</em> element and an 8-inch-wide <em>deps</em> element would be 8 inches wide.  A <em>dep</em> element with a 5-inch-wide <em>emps</em> element and a 3-inch-wide <em>deps</em> element would be 5 inches wide.)</p></li>
  <li><p>Every <em>deps</em> element should be as wide as the sum of all its <em>dep</em> elements' widths. (So, a <em>deps</em> element with a 3-inch-wide <em>dep</em>, a 5-inch-wide <em>dep</em>, and another 5-inch-wide <em>dep</em> would then be 13 inches wide.)</p></li>
  <li><p>A <em>dep</em> (or department) can have any number of <em>emp</em> elements (or employees) and any number of <em>dep</em> elements (or sub-departments), arbitrarily deep.</p></li>
  </ol>
  
  <p>The problem, then, that I want to solve in XSLT is how to transform a generic and recursively structured XML Source Document to an XML Result Docment where each (or most) element(s) should have some kind of calculated value attached to them that depends on the same or similar calculated value of its children... and so on... and so on... all the way down to whatever might be the "leaf node".</p>
  
  <p>Quick Edit: Thinking about it more, a similar example of this kind of problem would be to transform a "filesystem" XML Source Document to an XML Result Document in which a "file-count" attribute is added to every "folder" showing the total number of files in it and its "sub-folders", and their "sub-folders" and so on.</p>
  
  <p>Any help in learning how to do this--Even...  No. <em>Most especially</em> if there is more than one idiomatic way to do it--would be deeply appreciated.</p>