Alternatively, a way that might help if the elements to be inserted can vary by each run - using XML.modify to insert the child elements into the TopLevel document.
Each child XML could easily be included or not by the use of IF statements.
-- Store the top level xml in a table (variable) so it can be used in an UPDATE statement
declare @t table(x xml);
insert @t(x) values(@toplevel);
--== Add the Employees nodes into the toplevel XML ==--
-- This requires a loop as xml.modify doesn't allow multiple updates in one batch
while exists(
-- check if there are any unprocessed elements in the empinfo xml fragment
select 1
from @t
cross apply x.nodes('//Store') tl(store)
cross apply (select tl.store.value('(StoreNumber/text())[1]','int')) as store(number)
cross apply (select @empinfo.query('(//Store[StoreNumber/text()=sql:column("store.number")]/Employees)[1]')) emp(nd)
where x.exist('(//Store[StoreNumber/text()=sql:column("store.number")]/Employees)[1]')=0
)
update top(1) t
set x.modify('insert sql:column("emp.nd") as last into (//Store[StoreNumber/text()=sql:column("store.number")])[1]')
from @t AS t
cross apply x.nodes('//Store') tl(store) -- Process each Store
cross apply (select tl.store.value('(StoreNumber/text())[1]','int')) as store(number) -- convert the StoreNumber to a non-xml data type
cross apply (select cast(@empinfo.query('(//Store[StoreNumber/text()=sql:column("store.number")]/Employees)[1]') as xml)) emp(nd) -- find the related Employees for this store
where x.exist('(//Store[StoreNumber/text()=sql:column("store.number")]/Employees)[1]')=0 -- prevent updates of existing elements
--== Add the Address nodes into the toplevel XML ==--
while exists(
select 1
from @t
cross apply x.nodes('//Store') tl(store)
cross apply (select tl.store.value('(StoreNumber/text())[1]','int')) as store(number)
cross apply (select [highlight="#ffff11"]@addinfo[/highlight].query('(//Store[StoreNumber/text()=sql:column("store.number")]/[highlight="#ffff11"]Address[/highlight])[1]')) [highlight="#ffff11"]addr[/highlight](nd)
where x.exist('(//Store[StoreNumber/text()=sql:column("store.number")]/[highlight="#ffff11"]Address[/highlight])[1]')=0
)
update top(1) t
set x.modify('insert sql:column("[highlight="#ffff11"]addr[/highlight].nd") as last into (//Store[StoreNumber/text()=sql:column("store.number")])[1]')
from @t AS t
cross apply x.nodes('//Store') tl(store)
cross apply (select tl.store.value('(StoreNumber/text())[1]','int')) as store(number)
cross apply (select cast([highlight="#ffff11"]@addinfo[/highlight].query('(//Store[StoreNumber/text()=sql:column("store.number")]/[highlight="#ffff11"]Address[/highlight])[1]') as xml)) [highlight="#ffff11"]addr[/highlight](nd)
where x.exist('(//Store[StoreNumber/text()=sql:column("store.number")]/[highlight="#ffff11"]Address[/highlight])[1]')=0
select x from @t
I have used the test data from Matt's answer, and have sections for Employees and Address.
Each new section you want to add in is then just a "copy and paste" of an existing section, then edit the highlighted parts (as seen in the Address section of my code).
MM
select geometry::STGeomFromWKB(0x0106000000020000000103000000010000000B0000001000000000000840000000000000003DD8CCCCCCCCCC0840000000000000003DD8CCCCCCCCCC08408014AE47E17AFC3F040000000000104000CDCCCCCCCCEC3F9C999999999913408014AE47E17AFC3F9C99999999991340000000000000003D0000000000001440000000000000003D000000000000144000000000000000400400000000001040000000000000F03F100000000000084000000000000000401000000000000840000000000000003D0103000000010000000B000000000000000000143D000000000000003D009E99999999B93F000000000000003D009E99999999B93F8014AE47E17AFC3F400000000000F03F00CDCCCCCCCCEC3FA06666666666FE3F8014AE47E17AFC3FA06666666666FE3F000000000000003D1800000000000040000000000000003D18000000000000400000000000000040400000000000F03F000000000000F03F000000000000143D0000000000000040000000000000143D000000000000003D, 0);