A: 

Using XSLT 2.0 I would do this, but yours is easier to read anyway.

<xsl:template match="node1[.='']">
    <xsl:copy>
        <xsl:value-of select="if (following-sibling::node2[.!='']) then following-sibling::node2[.!=''] else if (preceding-sibling::node2[.!='']) then preceding-sibling::node2[.!=''] else 'Default'"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="node2[.='']">
    <xsl:copy>
        <xsl:value-of select="if (following-sibling::node1[.!='']) then '' else if (preceding-sibling::node1[.!='']) then '' else 'Default'"/>
    </xsl:copy>
</xsl:template>
Peter Lindqvist
I prefer XSLT 1.0 .. because Microsoft products don't support xslt 2.0 .. thanx for the response anyway .. :-)
infant programmer
+1  A: 
<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node1[.=''] | node2[.='']">
    <xsl:copy>
      <xsl:call-template name="GetOwnValue" />
    </xsl:copy>
  </xsl:template>

  <xsl:template name="GetOwnValue">
    <xsl:variable name="node2" select="following-sibling::node2[1]" />
    <xsl:choose>
      <xsl:when test="$node2 != ''">
        <xsl:value-of select="$node2" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>Default</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>
Tomalak
@Tomalak, If node1 isn't null and node2 is null, no need to update node2 .. node2 must be transformed as null itself .. Can you please update the answer with this condition? I tried but failed .. thank you ..
infant programmer
You should have stated this requirement in the question.
Tomalak
Well in my code unless I don't specify to update <node2> with Default text .. it doesn't do that .. But in your code the approach is converse .. So I made heedlessness to explicitly write that requirement ..
infant programmer
No need to accept an answer that does not work for you. ;)
Tomalak
I know .. but I liked the solution as it accomplishes most of my requirement and .. that's enough for me .. Well. There is really no harm in updating <node2/> but I just wanted to know the possibilities with the code ;)
infant programmer
There is an answer from me and it may be worth your attention :)
Dimitre Novatchev
A: 

I have modified Tomalak's answer and accomplished the requirement ..
As I have mentioned in my question, This code passes node2 as null (if it is null) if the sibling node1 isn't null (and also if there is no sibling node1) ..

This code finally became an alternative to the one I have posted in my Q .. (I don't say it is perfect enough .. but I am glad that I could try .. :-)
And this code is more efficient than mine by some 10-20 msecs .. :-)

Here it goes ..

  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node1[.=''] | node2[.='']">
    <xsl:copy>
      <xsl:call-template name="GetOwnValue">
        <xsl:with-param name="node">
          <xsl:value-of select="name()"/>
        </xsl:with-param>
      </xsl:call-template>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="GetOwnValue">
    <xsl:param name="node"/>
    <xsl:variable name="node2" select="following-sibling::node2[1]|preceding-sibling::node2[1]" />
    <xsl:variable name="node1" select="following-sibling::node1[1]|preceding-sibling::node1[1]" />
     <xsl:choose>
      <xsl:when test="$node2 != ''">
          <xsl:value-of select="$node2" />
      </xsl:when>
       <xsl:when test="$node!='node1' and ($node1!='' or not(following-sibling::node1[1]|preceding-sibling::node1[1]))"/>
      <xsl:otherwise>
          <xsl:text>Default</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
infant programmer
+2  A: 

I. XSLT 1.0 solution:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:variable name="vReplacement">Default</xsl:variable>

       <xsl:variable name="vRep" select=
        "document('')/*/xsl:variable[@name='vReplacement']/text()"/>

     <xsl:template match="node()|@*">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
     </xsl:template>

     <xsl:template match="node1[not(node())] | node2[../node1[not(node())]]">
      <xsl:copy>
          <xsl:copy-of select="../node2/text() | $vRep[not(current()/../node2/text())]"/>
      </xsl:copy>
     </xsl:template>
</xsl:stylesheet>

It is shorter and simpler than the current solutions -- 7 lines less and, more importantly, one template less than the currently selected solution.

Even more importantly, this solution is completely declarative and push-style -- no calling of named templates and the only <xsl:apply-templates> is in the identity rule.

II. XSLT 2.0 solution

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="node()|@*">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
 </xsl:template>

 <xsl:template match="node1[not(node())] | node2[../node1[not(node())]]">
  <xsl:copy>
      <xsl:sequence select="(../node2/text(), 'Default')[1]"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

Using the power of XPath 2.0 sequences this solution is quite shorter than the XSLT 1.0 solution.

Something similar is not possible in XSLT 1.0 (such as selecting the first of the union of two nodes without specifying predicates to make the two nodes mutually exclusive), because the node with the default text and the node1/node2 nodes belong to different documents and, as we know well, node ordering between nodes of different documents is implementation specific and is not guaranteed/prescribed.

This solution is completely declarative (no if/then/else) and completely push style: the only <xsl:apply-templates> is in the identity rule.

Dimitre Novatchev
+1 from me. Nice solution, very idiomatic.
Tomalak
This is what I was really looking for .. :-)
infant programmer
@Dimitre, I need a small clarification with XSLT 1.0 solution, Why do we need to declare one more variable (namely $vRep) and assign the value of the variable $vReplacement. Where as direct usage of $vReplacement gives an error (!) (I had tried this, long time back too) .. what would be the reason behind the error? Is that the bug with XSLT 1.0?
infant programmer
@infant-programmer: I want to use the <xsl:variable> as a *node*, not as value, because the union operator "|" is defined only on nodes. In XSLT 1.0 a reference to a variable gives us just the value of the variable. Unfortunately, if the value nas nested children elements, it is of the infamous RTF (Result Tree Fragment) type and its innards cannot be manipulated with XPath. There are three ways out of this: 1. Use a namespaced child node of xsl:stylesheet (with global scope). 2. Use an xsl:variable as a node (my choice here) and 3. Use the xxx:node-set() extension function.My choice: (2)
Dimitre Novatchev
@infant-programmer: More information about the RTF type: http://www.w3.org/TR/xslt#section-Result-Tree-Fragments and http://www.biglist.com/lists/xsl-list/archives/200304/msg01234.html
Dimitre Novatchev
yup. thank you so much. :-)
infant programmer