Parsing XML and replacing specific elements or attribute values via shell script

bash, shell, xml-parsing, xmllint, xmlstarlet

Solution

Update value with `xmllint` in `file.xml`:

xmllint --shell file.xml << EOF
cd /studentFile/student[studentName='CLASSA']/studentActions/studentAction[studentType='Juniour']/studentStatus
set failed
save
EOF

or without here document:

echo -e "cd /studentFile/student[studentName='CLASSA']/studentActions/studentAction[studentType='Juniour']/studentStatus\nset failed\nsave" | xmllint --shell file.xml

Update: With bash and XML in a variable:

xml=$(xmllint --shell <(echo "$xml") << EOF
cd /studentFile/student[studentName='CLASSA']/studentActions/studentAction[studentType='Juniour']/studentStatus
set failed
save -
EOF
)

or without here document:

xml=$(echo -e "cd /studentFile/student[studentName='CLASSA']/studentActions/studentAction[studentType='Juniour']/studentStatus\nset failed\nsave -" | xmllint --shell <(echo "$xml"))

Problem

For the below xml ,I need to replace `<studentStatus>` for `<studentName>CLASSA</studentName>` to `<studentStatus>failed</studentStatus>`. ``` <studentFile> <student> <studentName>CLASSA</studentName> <studentStatus>Success</studentStatus> <studentActions> <studentAction> <studentType>Juniour</studentType> <studentStatus>Completed</studentStatus> <studentMsg/> </studentAction> <studentAction> <studentType>HighSchool</studentType> <studentStatus>Completed</studentStatus> <studentMsg/> </studentAction> </studentActions> </student> <student> <studentName>CLASSB</studentName> <studentStatus>Success</studentStatus> <studentActions> <studentAction> <studentType>Senior</studentType> <studentStatus>Completed</studentStatus> </studentAction> <studentAction> <studentType>Middle</studentType> <studentStatus>Completed</studentStatus> </studentAction> </studentActions> </student> </studentFile> ``` What I got so far, ``` xmllint -xpath "/studentFile/student[studentName='CLASSA']/studentActions/studentAction[studentType="Juniour"]/studentStatus" myxml.xml ``` now i got the status of the student as Completed , now this value should be changed to Failed . Only for `<studentType>Juniour</studentType>`. How should I edit the xml inorder to get it as , ``` <studentFile> <student> <studentName>CLASSA</studentName> <studentStatus>Success</studentStatus> <studentActions> <studentAction> <studentType>Juniour</studentType> <studentStatus>Failed</studentStatus> <studentMsg/> </studentAction> <studentAction> <studentType>HighSchool</studentType> <studentStatus>Completed</studentStatus> <studentMsg/> </studentAction> </studentActions> </student> <student> <studentName>CLASSB</studentName> <studentStatus>Success</studentStatus> <studentActions> <studentAction> <studentType>Senior</studentType> <studentStatus>Completed</studentStatus> </studentAction> <studentAction> <studentType>Middle</studentType> <studentStatus>Completed</studentStatus> </studentAction> </studentActions> </student> </studentFile> ``` Can this be done using sed. I know there are tools like xsltproc but not sure if this is installed in all nodes in our cluster . Any help will be appreciated. Thanks in advance!

Original source

Related problems