XML Transform locate a node based on values in neighboring node

66 Views Asked by At

I'm trying to set attributes for a node that has no key or name, but it neighboring node can be identified by its name attribute. But I' really struggling to come up with a locator expression to choose the correct node.

The source xml is:

</configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            ...
            <dependentAssembly>
                <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
                <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
            </dependentAssembly>
            ...
        </assemblyBinding>
    </runtime>
</configuration>

and I tried

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            ...
            <dependentAssembly>
                <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" xdt:Transform="SetAttributes"
                    xdt:Locator="XPath(//../assemblyIdentity[@name='System.Web.WebPages'])"/>
            </dependentAssembly>
            ...
        </assemblyBinding>
    </runtime>
</configuration>

But it won't update the oldVersion attribute of the bindingRedirect node and if I omit the xdt:Locator="..." entirely it changes the value for all bindingRedirect nodes.

Update: Using this online xpath evaluator and the answer of Jack Fleeting I found an xpath expression which correctly selects the node I want

//dependentAssembly/assemblyIdentity[@name='System.Web.WebPages']/following-sibling::bindingRedirect

the problem now seams to be that the transform engine does not know how to handle this. I tried to use the transformations Replace and SetAttributes, none of which resulted in an update of the node. Any ideas.

1

There are 1 best solutions below

1
Jack Fleeting On

If you're trying to modify the value of <bindingRedirec>, your xpath expression doesn't select it.

try chainging

xdt:Locator="XPath(//../assemblyIdentity[@name='System.Web.WebPages'])"/>

to

xdt:Locator="XPath(//../assemblyIdentity[@name='System.Web.WebPages']/following-sibling::bindingRedirect)"/>

and see if it works.