XmlPeek可以读,但是XmlPoke不能写

本文关键字:XmlPoke 不能 但是 XmlPeek | 更新日期: 2023-09-27 18:09:52

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

下面是一个来自我的csproj文件(完整版本)的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不能写

只是想为遇到这种情况的任何人确认一下,实际上,这就是如何解决无法在XmlPeek任务和XmlPoke任务中使用完全相同的XPath查询的问题。

替换常规web.config中AppSettings元素的"file"属性值的原始查询:

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

为了获得XmlPeek任务中的"file"属性,我使用了以下XPath查询:

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

然而,同样的查询不会在XmlPoke任务中工作。相反,下面的工作就像@philip-pittle在他对问题 的更新中发现的那样

//appSettings [@file = ' devsettings.config '] /添加/…/@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 version 12.0.31101.0

[Microsoft .NET Framework, version 4.0.30319.18444]

可能是bug?但这绝对是奇怪的行为