Question:
Say for example I have a certain operation wich will transform an .xml file into a .txt file; in make terms I could have something like:

.xml.txt:
		    process -o $@ $**
	

I can see how to set up a msbuild target that can have inputs and outputs be properties, and explicitly invoke it via MSBuild actions, but that still doesn't come close. Ideally I want to be able to do something like iterate through an item set of xml files and apply the transform to each one in turn. Is there some technique I'm missing (other tyhan creating custom tasks, which to my mind doesn't scale well)?

Answer:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

		     [<ItemGroup>]
		          [<XmlFile] Include="a.xml"/>
		          [<XmlFile] Include="b.xml"/>
		          [<XmlFile] Include="c.xml"/>
		    [</ItemGroup>]
	

		    <Target Name="ProcessXml"
		        Inputs="@(XmlFile)"
		        Outputs="@(XmlFile->'%(Filename).txt')">
	

		        <Exec Command="process -o [@(XmlFile)] %(XmlFile.Filename).txt"/>
		    </Target>
	
</Project>

		 On the Exec, we invoke the task once per bucket of unique referenced metadata values. In this case the meta-data referenced is %(Filename), so we invoke it once per filename: the commands are 
	

		          process -o a.xml a.txt
		          process -o b.xml b.txt
		          process -o c.xml c.txt
	

If I'd wanted it all to go in at once I would have written @(XmlFile->'%(Filename).txt') which signifies a scalar, instead of %(XmlFile.Filename).txt, and would have gotten a command like "process -o a.xml;b.xml;c.xml a.txt;b.txt;c.txt"



To only process the out of date xml files I put Inputs on the targets and a transform of the Inputs on the outputs. MSBuild will notice the mapping and check the pairs of timestamps, then transparently only pass in the subset of out of date xml files.
Microsoft Communities