【问题标题】:MSBuild - XPath - XmlPeek can read but XmlPoke can not writeMSBuild - XPath - XmlPeek 可以读取但 XmlPoke 无法写入
【发布时间】:2014-06-23 16:33:36
【问题描述】:

我正在使用MSBuild 来操作我的项目 (.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/..?这是bug吗??

【问题讨论】:

  • 我认为这个问题的标题是一个错误。
  • 没错!很好,很抱歉。
  • 哇,这里我想为什么要先下一个元素,然后回溯,然后获取属性?它有效,没有任何意义,但它有效。谢谢!

标签: c# .net xml xpath msbuild


【解决方案1】:

只是想向遇到此问题的其他人确认,事实上,这就是您解决无法在 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]

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

【讨论】:

  • 很高兴听到我不是唯一一个遇到这个并且认为这很奇怪的人。感谢您的精彩文章,希望它可以帮助人们避免试图弄清楚这一点的痛苦!
  • 谢谢你,Philip,我想问一下你是怎么想到下拉一个节点,再回来然后使用属性的?
  • 老实说,我不记得了。我花了大约 30 个小时来设置我的全自动 Team City 以支持我的 Visual Studio 插件项目。不幸的是,这只是我必须解决的问题之一 (stackoverflow.com/questions/24328738/…)。在某个地方,我一定找到了建议 xpath 策略的博客文章或帮助文档。或者我蛮力强迫它并很幸运。
  • 我认为这与我提交给 MSBuild 的一个错误有关。 github.com/Microsoft/msbuild/issues/2051
猜你喜欢
  • 2022-11-10
  • 1970-01-01
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 2019-12-07
  • 1970-01-01
  • 1970-01-01
  • 2018-02-22
相关资源
最近更新 更多