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="//m开发者_开发知识库x: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>
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">
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>
精彩评论