4

I'm using MSBuild to manipulate my Project (.csproj) file to update a reference to a static file. The static file will be built by my CI Server (TeamCity) and then the reference the Project uses will need to be updated before the Project itself is built.

Here is an example of the Xml from my csproj file (full version):

<?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>

I have written an MSBuild Task:

<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>

But when I run it I get the message 0 replacements.

So I added an XmlPeek task to test the query:

<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)"/>

When I run MSBuild XmlPeek is able to read the Xml:

 Text: packages\pMixins.0.1.7.nupkg

The queries are exactly the same! Why can't XmlPoke manipulate the Xml if XmlPeek can read it?

UPDATE

After hours of playing with this, I finally found an XPath query that will get XmlPoke to do what I want:

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

Why is it necessary to add /n:IncludeInVSIX/..? Is this a bug??

Philip Pittle
  • 11,821
  • 8
  • 59
  • 123

1 Answers1

1

Just wanted to confirm for anyone else who encounters this, that this is how, in fact, you get around the issue of not being able to use the same exact XPath query in XmlPeek task and XmlPoke task.

Original query to replace "file" attribute value of AppSettings element in regular web.config:

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

To get at the "file" attribute in XmlPeek task I used following XPath query:

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

However this same query wouldn't work in XmlPoke task. Instead the following worked like what @philip-pittle discovered in his update to the question

//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)" />

This was using following versions of MSBuild.

Microsoft (R) Build Engine version 12.0.31101.0

[Microsoft .NET Framework, version 4.0.30319.18444]

May be it's a bug? But definitely odd behavior.

andryuha
  • 1,526
  • 3
  • 15
  • 31
  • It's nice to hear I am not the only one who ran into this and also thought it was quite odd. Thanks for the nice write up, hopefully it will save people the pain of trying to figure this one out! – Philip Pittle May 14 '15 at 18:02
  • Thank you Philip, I have to ask how did you think of dropping down a node, coming back up and then using attribute? – andryuha May 14 '15 at 18:09
  • Honestly, I don't recall. It took me about 30 hours to get my fully automated Team City set up to support my Visual Studio plugin project. This was unfortunately only one of the issues I had to solve (http://stackoverflow.com/questions/24328738/update-xml-file-vsixmanifest). Somewhere along the line I must have found a blog post or help document that suggested the xpath strategy. Or I brute forced it and got lucky. – Philip Pittle May 14 '15 at 18:29
  • I think this is related to a bug I submitted to MSBuild. https://github.com/Microsoft/msbuild/issues/2051 – Void Star Jun 06 '17 at 20:17