Search code examples
xmlxpathxmlstarlet

Targeting XML starlet to only hit the element below top level element


<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
    <fields>
        <fullName>Summary__c</fullName>
        <defaultValue>false</defaultValue>
        <deprecated>false</deprecated>
        <externalId>false</externalId>
        <inlineHelpText>Dummy Text.</inlineHelpText>
        <label>Summary</label>
        <trackTrending>false</trackTrending>
        <type>Checkbox</type>
    </fields>
    <label>Object Name</label>
</CustomObject>

I have the above XML and trying to run the following command (with $f being a variable reference to the file):

xmlstarlet ed -L -N x="http://soap.sforce.com/2006/04/metadata" -u "//x:label" -v 'test' $f;

The goal is to modify the label element with "Object Name" to "test" but not the label called "Summary". However both are being changed.

I've tried to modify the selector to do "CustomObject/label" but that doesn't seem to select correctly.

Anyone have any thoughts to only hit the "Object Name" label.


Solution

  • I think you were super close. Try this xpath instead...

    /x:CustomObject/x:label
    

    updated command line...

    xmlstarlet ed -L -N x="http://soap.sforce.com/2006/04/metadata" -u "/x:CustomObject/x:label" -v 'test' $f;
    

    Also, since you're only trying to select the x:label that's a direct child of the root element, you could use this shorter xpath too...

    /*/x:label