'How to replace field in XML file using xmllint or xmlstarlet?

I have the following xml file:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:aut="http://">
   <soapenv:Header>
      <aut:Session>
         <aut:IPAddress>127.0.0.1</aut:IPAddress>
         <aut:SessionToken>true</aut:SessionToken>
         <aut:ApplicationToken>861</aut:ApplicationToken>
      </aut:Session>
   </soapenv:Header>
   <soapenv:Body></soapenv:Body>
</soapenv:Envelope>

What is the best way to replace <aut:SessionToken>true</aut:SessionToken> by <aut:SessionToken>false</aut:SessionToken> ?

Here is what I'm trying:

xmllint --shell file.xml << EOF
cd //*[local-name() = "Header"]/*[local-name() = "Session"]/text()/*[local-name() = "SessionToken"]/text()
set failed
save
EOF

I'm having problems because of namespace when I try to replace true for false.

Br, JD



Solution 1:[1]

When dealing with a SOAP envelope I wouldn't use *[local-name() = "…"] which ignores the namespace. Instead, use an explicit namespace binding.

To toggle the boolean, for example

xmlstarlet edit -N aut="http://" \
    --var T '//aut:Session/aut:SessionToken' \
    -u '$T' -x 'not($T)' file.xml 

Add -L / --inplace before -N to edit the file in-place.

To read its value:

xmlstarlet select -N aut="http://" \
    -t -v '//aut:Session/aut:SessionToken' -n file.xml

Solution 2:[2]

You're almost there. You just have an extra text() element in there. In xmlstartlet, try

    xml ed -u '//*[local-name() = "Header"]/*[local-name() = "Session"] \
//*[local-name() = "SessionToken"]//text()' -v "false" yourfile.xml

Solution 3:[3]

Your approach with xmllint is not far from correct. Just needs to add namespace handling and use namespace prefixes in XPath expression.

setrootns
cd //soapenv:Header/aut:Session/aut:SessionToken
set failed
save

As a one-liner:

echo -e "setrootns\n cd //soapenv:Header/aut:Session/aut:SessionToken\n set failed\n save\n bye" | xmllint --shell test.xml

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jack Fleeting
Solution 3 LMC