<xsl:sort />
should hep.
In your case it would be:
<xsl:sort select="name()"/>
Therefore try:
<xsl:for-each select="child::*[name()='a' or name() = 'b' or name() = 'c' or name() = 'd' or name() = 'e'][string-length(.)>0]">
<xsl:sort select="name()"/>
<xsl:if test="position() <= 3">
<xsl:value-of select="name()"/>
</xsl:if>
</xsl:for-each>
Update: Because in real live input XML there is not useful information to sort by you may add some meta information. Where to store the meta information depend on the capabilities of the xslt processor.
If you can use the node-set() extension you may try something like this:
Add a variable to stylesheet with expected order.
xsl:variable name="myOrder">
<order name="a" pos="1" />
<order name="b" pos="3" />
<order name="c" pos="2" />
<order name="d" pos="4" />
<order name="e" pos="5" />
</xsl:variable>
Make this variable usable as node-set by:
<xsl:variable name="Order" select="exsl:node-set($myOrder)" />
Sort with help of this variable.
<xsl:sort select="$Order/order[@name= name(current())]/@pos"/>