我正在使用MSBuild操纵我的Project(.csproj)文件来更新对静态文件的引用。静态文件将由我的CI服务器(TeamCity)构建,然后在构建项目本身之前需要更新项目使用的引用。

这是我的csproj文件(full version)中的Xml的示例:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build"
     xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
     ToolsVersion="12.0">
 <ItemGroup>
    <Content Include="packages\pMixins.0.1.7.nupkg">
       <IncludeInVSIX>true</IncludeInVSIX>
    </Content>


我写了一个MSBuild任务:

<Target Name="ReplaceNugetPackageDependency" BeforeTargets="PrepareForBuild" >
<XmlPoke
    XmlInputPath="$(MSBuildProjectFile)"
    Query="//n:Project/n:ItemGroup/
                n:Content[starts-with(@Include, 'packages')]/@Include"
    Value="TEST-TEST"
    Namespaces="&lt;Namespace Prefix='n'
                Uri='http://schemas.microsoft.com/developer/msbuild/2003'
                Name='DoNotKnowWhatThisIsFor-ButItIsRequired' /&gt;" >
 </XmlPoke>
 </Target>


但是当我运行它时,我收到消息0 replacements

所以我添加了一个XmlPeek任务来测试查询:

<XmlPeek
    XmlInputPath="$(MSBuildProjectFile)"
    Query="/n:Project/n:ItemGroup/
            n:Content[starts-with(@Include, 'packages')]/@Include"
    Namespaces="&lt;Namespace Prefix='n'
                Uri='http://schemas.microsoft.com/developer/msbuild/2003'
                Name='DoNotKnowWhatThisIsFor-ButItIsRequired' /&gt;">
         <Output TaskParameter="Result" ItemName="Peeked" />
</XmlPeek>
<Message Text="Text: @(Peeked)"/>


当我运行MSBuild XmlPeek时,可以读取Xml:

 Text: packages\pMixins.0.1.7.nupkg


查询是exactly一样! Why can't XmlPoke manipulate the Xml if XmlPeek can read it?

更新

经过数小时的研究,我终于找到了一个XPath查询,该查询将使XmlPoke做我想做的事情:

Query="//n:Project/n:ItemGroup/
        n:Content[starts-with(@Include, 'packages')]/n:IncludeInVSIX/../@Include"


为什么必须添加/n:IncludeInVSIX/..?这是一个错误吗?

最佳答案

只是想向遇到此问题的其他人确认,实际上,这就是您如何解决无法在XmlPeek任务和XmlPoke任务中使用完全相同的XPath查询的问题。

原始查询以替换常规web.config中AppSettings元素的“文件”属性值:

  <appSettings file="devsettings.config">
    <add key="BuildVersion" value="" />
  </appSettings>


为了获得XmlPeek任务中的“文件”属性,我使用了以下XPath查询:


  //appSettings[@file='devsettings.config']/@file


但是,此查询不适用于XmlPoke任务。相反,以下内容的工作方式类似于@ philip-pittle在问题更新中发现的内容


  //appSettings[@file='devsettings.config']/add/../@file


  <XmlPeek XmlInputPath="$(_BuildPath)web.config"
      Query="//appSettings[@file='devsettings.config']/@file">
    <Output TaskParameter="Result" ItemName="ExistingPeeked" />
  </XmlPeek>
  <XmlPoke XmlInputPath="$(_BuildPath)web.config"
    Query="//appSettings[@file='devsettings.config']/add/../@file"
    Value="$(_EnvironmentConfig)" />


这是使用以下版本的MSBuild。

Microsoft(R)Build Engine版本12.0.31101.0

[Microsoft .NET Framework版本4.0.30319.18444]

可能是错误吗?但是绝对是奇怪的行为。

10-06 02:01