Home > OS >  How to replace field in XML file using xmllint or xmlstarlet?
How to replace field in XML file using xmllint or xmlstarlet?

Time:03-01

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

CodePudding user response:

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

CodePudding user response:

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
  • Related