The problem is that you data does not contain an order criteria and sets in SQL Server only guarantee order when using an ORDER BY clause.
Due to implementation nodes() returns nodes in-order, so you can apply ROW_NUMBER(), e.g.
SELECT x.value('element[1]', 'INT') ,
ROW_NUMBER() OVER ( ORDER BY x ) AS RN
FROM xml.nodes('/') A(x);
when run MAXDOP 1, then it should work. If MAXDOP > 1 or in edge cases this may fail, just because there is no guarantee for the order in the set processing.
The only way I'm aware of is to create that order in the XML using XML processing, where order is guaranteed. Either by preprocessing it using XSLT or using FLOWR.
E.g.
DECLARE @xml AS XML = '<?xml version="1.0" encoding="us-ascii" ?>
<TreeView>
<node text="Asia">
<node text="China">
<node text="Beijing"/>
</node>
<node text="Pakistan"/>
<node text="India"/>
<node text="Sri Lanka"/>
</node>
<node text="Europe">
<node text="Germany"/>
</node>
<node text="America"/>
<node text="Africa"/>
</TreeView>';
SELECT Q.n.value('./@text', 'NVARCHAR(255)') ,
Q.n.value('let $currentNode := . return count(../node[. << $currentNode])', 'INT')
FROM @xml.nodes('/TreeView/node') Q(n)
ORDER BY 1;
And the final tree parsing is applying the above to a hierarchic CTE:
WITH Hierarchy
AS ( SELECT A.n.value('./@text', 'NVARCHAR(255)') AS NodeText ,
A.n.query('.') AS CurrentNode ,
0 AS NodeLevel ,
'\\' + A.n.value('let $currentNode := . return count(../node[. << $currentNode])', 'VARCHAR(MAX)') AS NodePath
FROM @xml.nodes('/TreeView/node') A(n)
UNION ALL
SELECT C.n.value('./@text', 'NVARCHAR(255)') AS NodeText ,
C.n.query('.') AS CurrentNode ,
P.NodeLevel + 1 ,
P.NodePath + '\' + C.n.value('let $currentNode := . return count(../node[. << $currentNode])', 'VARCHAR(MAX)') AS NodePath
FROM Hierarchy P
CROSS APPLY P.CurrentNode.nodes('node/node') C(n) )
SELECT NodeText ,
REPLICATE(SPACE(4), NodeLevel) + NodeText ,
NodeLevel ,
NodePath
FROM Hierarchy
ORDER BY NodePath;