You can retrieve all names without a CTE and CROSS APPLY as well:
DECLARE @x XML;
SET @x = '<Employees>
<Employee ID="101">
<Name>Jacob</Name>
<Department>IT</Department>
</Employee>
<Employee ID="354">
<Name>Steve</Name>
<Department>IT</Department>
</Employee>
<Employee ID="456">
<Name>Bob</Name>
<Department>IT</Department>
</Employee>
<Employee ID="478">
<Name>Joe</Name>
<Department>IT</Department>
</Employee>
<Employee ID="981">
<Name>Louis</Name>
<Department>IT</Department>
</Employee>
</Employees>';
-- select "Name"
WITH Num(i)
AS
(
SELECT 1
UNION ALL
SELECT i + 1
FROM Num
WHERE i < (SELECT @x.value('count(/Employees/Employee)','int') )
)
SELECT x.value('Name[1]', 'VARCHAR(20)')
FROM Num
CROSS APPLY @x.nodes('/Employees/Employee[position()=sql:column("i")]') e(x);
That's if you really want to use the position() function. Without using position() it gets a little simpler:
SELECT x.value('Name[1]', 'VARCHAR(20)')
FROM @x.nodes('/Employees/Employee') e(x);