c3rin
c3rin

Reputation: 1917

How do I update an xml file with msbuild with two namespaces?

This msbuild below task can take into account one namespace, but in the case where I'm updating an mxml (flex) that has a mix of namespaces, can I use this task or another msbuild task to do the update?

<XmlUpdate
        Prefix="fx"
        Namespace="http://ns.adobe.com/mxml/2009"
      XmlFileName="myFlexApp.mxml"
      Xpath="//mx:Application/fx:Declarations/fx:String[@id='stringId']"
      Value="xxxxx">

Here is the flex xml I'm trying to update:

<mx:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:mx="library://ns.adobe.com/flex/mx" 
            xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Declarations>
    <fx:String id="stringId">UPDATE_ME</fx:String>
</fx:Declarations></mx:Application>

Upvotes: 0

Views: 1359

Answers (2)

c3rin
c3rin

Reputation: 1917

I was able to successfully update the source for XmlUpdate so that it takes multiple namespaces:

            if (!string.IsNullOrEmpty(_prefix) && !string.IsNullOrEmpty(_namespace))
            {
                string[] prefixes = _prefix.Split(';');
                string[] namespaces = _namespace.Split(';');

                if (prefixes.Length != namespaces.Length)
                    throw new Exception("The number of prefixes is different from the number of namespaces");

                for (int prefixIndex = 0; prefixIndex < prefixes.Length; prefixIndex++)
                {
                    manager.AddNamespace(prefixes[prefixIndex], namespaces[prefixIndex]);                        
                }
            }

This works with the example of

<XmlUpdate
    Prefix="fx;mx"
    Namespace="http://ns.adobe.com/mxml/2009;library://ns.adobe.com/flex/mx"
  XmlFileName="myFlexApp.mxml"
  Xpath="//mx:Application/fx:Declarations/fx:String[@id='stringId']"
  Value="xxxxx">

Upvotes: 1

Julien Hoarau
Julien Hoarau

Reputation: 49970

You'll have to use XmlMassUpdate task. (This task is from MSBuild Community Tasks)

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <!-- The replacement value is here -->
  <!-- ProjectExtensions keep MSBuild to try to evaluate the content -->
  <ProjectExtensions>
    <ReplacementNode>
      <String id="stringId">CHANGE</String>
    </ReplacementNode>
  </ProjectExtensions>

  <Target Name="XmlUpdate">
    <XmlMassUpdate 
      ContentFile="myFlexApp.mxml"   
      NamespaceDefinitions="msb=http://schemas.microsoft.com/developer/msbuild/2003;
                           fx=http://ns.adobe.com/mxml/2009;
                           mx=library://ns.adobe.com/flex/mx" 
      ContentRoot="//mx:Application/fx:Declarations/fx:String[@id='stringId']" 
      SubstitutionsFile="$(MSBuildProjectFullPath)" 
      SubstitutionsRoot="msb:Project/msb:ProjectExtensions/msb:ReplacementNode/msb:String"/>
  </Target>
</Project>

Changing the value during execution

The tricky part is that you can't define a value on fly using XmlMassUpdate only, you'll need to use XmlUpdate to update the value in your replacement node first.

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <!-- The replacement value is here -->
  <!-- ProjectExtensions keep MSBuild to try to evaluate the content -->
  <ProjectExtensions>
    <ReplacementNode>
      <String id="stringId">CHANGE</String>
    </ReplacementNode>
  </ProjectExtensions>

  <Target Name="XmlUpdate" DependsOnTargets="ChangeXmlValue">
    <XmlMassUpdate 
      ContentFile="myFlexApp.mxml"   
      NamespaceDefinitions="msb=http://schemas.microsoft.com/developer/msbuild/2003;
                           fx=http://ns.adobe.com/mxml/2009;
                           mx=library://ns.adobe.com/flex/mx" 
      ContentRoot="//mx:Application/fx:Declarations/fx:String[@id='stringId']" 
      SubstitutionsFile="$(MSBuildProjectFullPath)" 
      SubstitutionsRoot="msb:Project/msb:ProjectExtensions/msb:ReplacementNode/msb:String"/>
  </Target>

  <Target Name="ChangeXmlValue">
    <XmlUpdate Prefix="n" 
               Namespace="http://schemas.microsoft.com/developer/msbuild/2003" 
               XPath="n:Project/n:ProjectExtensions/n:ReplaceNode/n:String/text()" 
               XmlFileName="$(MSBuildProjectFullPath)" 
               Value="$(NewValue)" />
  </Target>

</Project>

Upvotes: 0

Related Questions