I really like this question since I use a lot of XML for bulk inserts of business objects.
And thank you to Paul and everyone, I just learned that Cross Apply method seems to be about 5x faster. Never though of that method.
DECLARE @x xml
SET @X =
N'<toys>
<myToy>
<name>Train</name>
<components>
<part><name>engine</name><howMany>1</howMany></part>
<part><name>coaches</name><howMany>10</howMany></part>
<part><name>caboose</name><howMany>1</howMany></part>
<part><name>tracks</name><howMany>125</howMany></part>
<part><name>switches</name><howMany>8</howMany></part>
<part><name>power controller</name><howMany>1</howMany></part>
</components>
</myToy>
<myToy>
<name>remote control car</name>
<components>
<part><name>remote control</name><howMany>1</howMany></part>
<part><name>car</name><howMany>1</howMany></part>
<part><name>batteries</name><howMany>8</howMany></part>
</components>
</myToy>
</toys>
';
SELECT
[name] = T1.Toy.value('name[1]','VARCHAR(20)'),
componentname = T2.Part.value('name[1]','VARCHAR(20)'),
numberOfItems = T2.Part.value('howMany[1]','TINYINT')
FROM @x.nodes('/toys/myToy') T1(Toy)
CROSS APPLY
T1.Toy.nodes('./components/part') T2(Part)
SELECT
[name] = T2.Part.value('../../name[1]','VARCHAR(20)'),
componentname = T2.Part.value('name[1]','VARCHAR(20)'),
numberOfItems = T2.Part.value('howMany[1]','TINYINT')
FROM @x.nodes('/toys/myToy/components/part') T2(Part)