views:

143

answers:

1

Hi, i want to use MSBuild to insert a custom xml element into web.config. After looking up online, i found such solution:

1) Store element in the .build file in projectextensions

<ProjectExtensions>
 <CustomElement name="CustomElementName">
  ...
 </CustomElement>
</ProjectExtensions>

2) Retrieve the element with GetValue

<Target name="ModifyConfig">
<XmlFile.GetValue Path="$(MSBuildProjectFullPath)"
               XPath="Project/ProjectExtensions/CustomElement[@name='CustomElementName']">
            <Output TaskParameter="Value" PropertyName="CustomElementProperty"/>
</XmlFile.GetValue>
</Target>

This will not work as i need to reference a namespace the .build project is using for it to find the needed element (checked the .build file with XPath Visualizer). So, i look up for a further solution and come to this:

<ItemGroup>
        <XmlNamespace Include="MSBuild">
            <Prefix>msb</Prefix>
            <Uri>http://schemas.microsoft.com/developer/msbuild/2003&lt;/Uri&gt;
        </XmlNamespace>
</ItemGroup>

<Target name="ModifyConfig">
<XmlFile.GetValue Path="$(MSBuildProjectFullPath)" Namespaces="$(XmlNamespace)"
               XPath="/msb:Project/msb:ProjectExtensions/msb:CustomElement[@name='CustomElementName']"
                 >
            <Output TaskParameter="Value" PropertyName="CustomElementProperty"/>
</XmlFile.GetValue>
</Target>

But for some reason namespace is not recognized - MSBuild reports the following error:

C:...\mybuild.build(53,9): error : A task error has occured. C:...\mybuild.build(53,9): error : Message = Namespace prefix 'msb' is not defined.

I tried some variations of referencing it differently but none work, and there is not much about propertly referencing those namespaces online also. Can you tell me what am i doing wrong and how to do it propertly?

+1  A: 

I would recommend using a custom task from MSBuild Community Tasks called XmlMassUpdate for inserting a custom XML element into an xml file.

<XmlMassUpdate 
ContentFile="web.config" 
SubstitutionsFile="changes.xml" 
ContentRoot="/configuration/system.web" 
SubstitutionsRoot="/system.web" /> 

You can also reference the XML directly in the project file like this:

<XmlMassUpdate ContentFile="web.config" ContentRoot="/configuration/system.web"
    NamespaceDefinitions="msb=http://schemas.microsoft.com/developer/msbuild/2003"
    SubstitutionsFile="$(MSBuildProjectFullPath)"
    SubstitutionsRoot="/msb:Project/msb:ProjectExtensions/msb:system.web" />

However, the tile of your question seems to suggest you have problems getting XML values first not changing them. The mentioned lib does also have the XmlQuery task, which reads values from XML files and populates parameters based on those values.

mfloryan
I haven't worked with XmlMassUpdate before, but as i see from initial search it's best used for substitutions, while i need to get the element and insert it to a certain location in target document's xml hierarchy. Is that possible with XmlMassUpdate?
æther
I would think this should be possible - yes. You could perhaps update a single tag with multiple ones?
mfloryan
That sounds like a solution, but i would really prefer to use Microsoft.Sdc.XMLFile.AddElement for this task. Thank you for your input mfloryan, i will try XMLMassUpdate if i won't find a way to reference namespace for GetValue propertly.
æther