2011-04-14 92 views
19

我想在MSBuild任务中创建一个XML文件。如何使用MSBuild创建XML文件?

我有文件的列表:

<CreateItem Include="$(TestsAssembliesOutputDir)\Emidee.*.Tests.dll"> 
    <Output ItemName="TestsAssemblies" TaskParameter="Include" /> 
</CreateItem> 

我想创建一个XML这看起来像:

<?xml version="1.0" encoding="utf-8"?> 
<xunit> 
    <assemblies> 
    <assembly filename="PATH OF FILE #1" shadow-copy="true" /> 
    <assembly filename="PATH OF FILE #2" shadow-copy="true" /> 
    </assemblies> 
</xunit> 

我怎样才能做到这一点?

在此先感谢

迈克

回答

29

快速和肮脏......

<Target Name="CreateXml"> 
    <ItemGroup> 
    <TestAssembly Include="$(TestsAssembliesOutputDir)\Emidee.*.Tests.dll" /> 
    <Line Include="line01"><Text>&lt;xunit&gt;</Text></Line> 
    <Line Include="line02"><Text>&lt;assemblies&gt;</Text></Line> 
    <Line Include="line03"><Text>&lt;assembly filename=&quot;%(TestAssembly.Identity)&quot; shadow-copy=&quot;true&quot; /&gt;</Text></Line> 
    <Line Include="line04"><Text>&lt;/assemblies&gt;</Text></Line> 
    <Line Include="line05"><Text>&lt;/xunit&gt;</Text></Line> 
    <LineText Include="%(Line.Text)" /> 
    </ItemGroup> 
    <WriteLinesToFile 
    File="out.xml" 
    Lines="@(LineText)" 
    Overwrite="true" 
    /> 
</Target> 

留作练习你

  • 初始<? XML行
  • 压痕(提示使用CDATA内<'文本>)

您也可以使用下面的WriteLinesToFile并省略合成@(LineText)

Lines="@(Line->'%(Text)')" 
0

一种选择是使用内联任务。这允许您编写任意C#代码来生成Xml,这可能比其他解决方案更容易(或可能更难)。下面是我用来在我的构建中将NuGet nuspec文件一起破解的示例。

... 
<UsingTask 
     TaskName="CreateNugetPackage" 
     TaskFactory="CodeTaskFactory" 
     AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" 
    > 
     <ParameterGroup> 
      <ProjectName ParameterType="System.String" Required="true" /> 
      <Version ParameterType="System.String" Required="true" /> 
      <BaseFolder ParameterType="System.String" Required="true" /> 

      <Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" /> 
      <OutputFile ParameterType="Microsoft.Build.Framework.ITaskItem" Required="true" /> 
     </ParameterGroup> 

     <Task> 
      <Reference Include="System.Xml" /> 
      <Using Namespace="System" /> 
      <Using Namespace="System.Xml" /> 
      <Code Type="Fragment" Language="cs"> 
       <![CDATA[ 
       var root = Path.GetFullPath(BaseFolder);  

       using (var w = XmlWriter.Create(OutputFile.ItemSpec)) { 
        var ns = "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"; 
        w.WriteStartElement("package", ns); 

        w.WriteStartElement("metadata"); 

        w.WriteStartElement("id"); 
        w.WriteValue(ProjectName); 
        w.WriteEndElement(); 
        w.WriteStartElement("version"); 
        w.WriteValue(Version); 
        w.WriteEndElement(); 
        w.WriteStartElement("description"); 
        w.WriteValue("Test"); 
        w.WriteEndElement(); 

        w.WriteStartElement("authors"); 
        w.WriteValue("Test"); 
        w.WriteEndElement(); 

        w.WriteEndElement(); 


        w.WriteStartElement("files"); 

        foreach(var file in Files) { 
         w.WriteStartElement("file"); 
         var inFile = file.ItemSpec; 
         inFile = inFile.Replace(root, ""); 
         w.WriteAttributeString("src", inFile); 
         w.WriteAttributeString("target", inFile); 
         w.WriteEndElement(); 
        } 

        w.WriteEndElement(); 

        w.WriteEndElement(); 
       } 

    ]]> 
      </Code> 
     </Task> 
    </UsingTask> 


    <Target Name="CreateNuspec" BeforeTargets="BuildNugetPackage"> 

     <CreateNugetPackage 
      Files="@(Artifacts)" 
      OutputFile="$(NugetPackageSpec)" 
      ProjectName="$(ProjectName)" 
      BaseFolder="$(ArtifactRoot)" 
      Version="$(Version)" 
      /> 
    </Target> 
... 

一些相关文档:

UsingTaskElement

MSBuild inline tasks