There are actually a few ways to solve this with the XML Path syntax.
The first is to UNPIVOT your results first, for example:
SELECT item as [text()]
FROM
(select col1, col2, col3 from tbl) p
UNPIVOT
(item FOR colHeading IN (col1, col2, col3)) AS unpvt
FOR XML PATH ('item'), ROOT ('parent')
The 2nd doesn't require the unpivot, but repeats more of your query:
select (select col1 as [text()] from tbl for xml path('item'), type)
, (select col2 as [text()] from tbl for xml path('item'), type)
, (select col3 as [text()] from tbl for xml path('item'), type)
for xml path ('parent')
Both of these will combine multiple rows of data all under the same parent node. For example, if you have 2 rows, the first with 1,2,3 and the second 4,5,6, you'd get:
<parent>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
</parent>
If, instead, you want each row you unpivot to have a unique parent element per row, then, assuming you have some row identifier on each row (I'll call it parentId), you can group these by that row by tweaking these approaches:
SELECT
(
SELECT item as [text()]
FROM
(select parentId, col1, col2, col3 from tbl tt where tt.parentid = t.parentid) p
UNPIVOT
(item FOR colHeading IN (col1, col2, col3)) AS unpvt
FOR XML PATH ('item'), TYPE
)
FROM tbl t
FOR XML PATH ('parent')
or
select (select col1 as [text()] from tbl tt where t.parentid = tt.parentid for xml path('item'), type)
, (select col2 as [text()] from tbl tt where t.parentid = tt.parentid for xml path('item'), type)
, (select col3 as [text()] from tbl tt where t.parentid = tt.parentid for xml path('item'), type)
from tbl t
for xml path ('parent')
Which would result in:
<parent>
<item>1</item>
<item>2</item>
<item>3</item>
</parent>
<parent>
<item>4</item>
<item>5</item>
<item>6</item>
</parent>
Sql Fiddle with demo