tags:

views:

18

answers:

2

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

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"&gt;

  <!-- 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"&gt;

  <!-- 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>
madgnome
I can't get this to work for the textnode ('CHANGE'). I can get an xmlmassupdate to put an xmlnode in (ie. <XXX/>) but not the textnode.
c3rin
A: 

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