Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

msbuild array iteration

Tags:

msbuild

<ItemGroup>
    <!-- Unit Test Projects-->
    <MyGroup Include="Hello.xml" />
    <MyGroup Include="GoodBye.xml" />     
</ItemGroup>

How do I make a task that iterates through this list and does something?

<XmlPeek XmlInputPath="%(MyGroup.Identity)"
         Query="/results">
    <Output TaskParameter="Result"
            ItemName="myResult" />
</XmlPeek>

I want to thow an error message if myresult has a certain text inside of it. However for the life of me I can't figure out how to iterate through arrays in Msbuild... anyone know how to accomplish this?

like image 280
zachary Avatar asked Jun 15 '10 13:06

zachary


2 Answers

You need to use batching for this. Batching will iterate over a set of items based on a metadata key. I've put together a bunch of material on this at http://sedotech.com/Resources#batching. For example take a look at this simple MSBuild file.

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

  <ItemGroup>
    <Files Include="one.txt"/>
    <Files Include="two.txt"/>
    <Files Include="three.txt"/>
    <Files Include="four.txt"/>
  </ItemGroup>

  <Target Name="Demo">
    <Message Text="Not batched: @(Files->'%(Identity)')"/>

    <Message Text="========================================"/>

    <Message Text="Batched: %(Files.Identity)"/>
  </Target>

</Project>

When you build the Demo target the results are

Not batched: one.txt;two.txt;three.txt;four.txt
========================================
Batched: one.txt
Batched: two.txt
Batched: three.txt
Batched: four.txt

Batching always uses the syntax %(Xyz.Abc). Take a look thorough those links for more info about batching then you ever wanted to know.

like image 94
Sayed Ibrahim Hashimi Avatar answered Sep 28 '22 07:09

Sayed Ibrahim Hashimi


You could use batching on an inner target, like that :

<ItemGroup>
  <!-- Unit Test Projects-->
  <MyGroup Include="Hello.xml" />
  <MyGroup Include="GoodBye.xml" />     
</ItemGroup>

<Target Name="CheckAllXmlFile">
  <!-- Call CheckOneXmlFile foreach file in MyGroup -->
  <MSBuild Projects="$(MSBuildProjectFile)"
           Properties="CurrentXmlFile=%(MyGroup.Identity)"
           Targets="CheckOneXmlFile">
  </MSBuild>
</Target>

<!-- This target checks the current analyzed file $(CurrentXmlFile) -->
<Target Name="CheckOneXmlFile">
  <XmlPeek XmlInputPath="$(CurrentXmlFile)"
           Query="/results/text()">
    <Output TaskParameter="Result" ItemName="myResult" />
  </XmlPeek>

  <!-- Throw an error message if Result has a certain text : ERROR -->
  <Error Condition="'$(Result)' == 'ERROR'"
         Text="Error with results $(Result)"/> 
</Target>
like image 39
Julien Hoarau Avatar answered Sep 28 '22 07:09

Julien Hoarau