Search code examples
xmlbashshellxmlstarlet

How to check if a subnode exists using xmlstarlet and bash?


I have a script that is adding a subnode to my XML file, and it is working fine.

Problem is I'm running this script lots of time and I only want to add my subnode once, So what I need is to check if it exists and if it does do nothing if it doesn't exist I want to create it. (In my example create subnode with the name 66.66.66)

#!/bin/bash
LOCK_BRANCH="66.66.66" 
#Adding a new subnode to certain nodes
xmlstarlet ed -L --subnode  "/configurations/rules" --type elem -n rule config.xml

#Adding text to the new node
xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n name -v "$LOCK_BRANCH" config.xml
xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n repo -v "mqm" config.xml
xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n branch -v "refs/heads/12.55.99" config.xml
xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n emailTo -v "imichael@gmail.com" config.xml
xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n path -v "Server/.*/schema/v.*/.*/.*-dbSchemaDescriptor\.xml,Server/.*/resources/" config.xml

This is the original XML file:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<configurations>
    <smtpHost>smtp3.gmail.com</smtpHost>
    <smtpPort>25</smtpPort>
    <emailFrom>GitPushNotifier@gmail.com</emailFrom>
    <emailSubject>Push notification</emailSubject>
    <!-- Stash general URL-->
    <gitViewerURL>http://server0005.gmail.net:7990/projects/</gitViewerURL>
  <rules>
    <rule>
        <name>test_12.55.4</name>
        <repo>test</repo>
        <branch>refs/heads/12.55.4</branch>
        <emailTo>test@gmail.com</emailTo>
        <path>Server/.*/resources/schema/v.*/.*/.*-dbSchemaDescriptor\.xml,Server/.*/resources/SpringIOC/dataupgrader/v.*/.*/.*-dataUpgrader\.xml,Server/.*/java/com/hp/test/dataupgrader/v.*/.*/.*\.java,Server/.*/resources/indexes/v.*/.*\.index,Server/.*/resources/SpringIOC/vanilla/.*\.xml</path>
    </rule>
    <rule>
        <name>test_12.55.10</name>
        <repo>test</repo>
        <branch>refs/heads/12.55.10</branch>
        <emailTo>test@gmail.com</emailTo>
        <path>Server/.*/resources/schema/v.*/.*/.*-dbSchemaDescriptor\.xml,Server/.*/resources/SpringIOC/dataupgrader/v.*/.*/.*-dataUpgrader\.xml,Server/.*/java/com/hp/test/dataupgrader/v.*/.*/.*\.java,Server/.*/resources/indexes/v.*/.*\.index,Server/.*/resources/SpringIOC/vanilla/.*\.xml</path>
    </rule>
    <rule>
        <name>test_12.55.6</name>
        <repo>test</repo>
        <branch>refs/heads/12.55.6</branch>
        <emailTo>test@gmail.com</emailTo>
        <path>Server/.*/resources/schema/v.*/.*/.*-dbSchemaDescriptor\.xml,Server/.*/resources/SpringIOC/dataupgrader/v.*/.*/.*-dataUpgrader\.xml,Server/.*/java/com/hp/test/dataupgrader/v.*/.*/.*\.java,Server/.*/resources/indexes/v.*/.*\.index,Server/.*/resources/SpringIOC/vanilla/.*\.xml</path>
    </rule>
  </rules>
</configurations>

Solution

  • After looking a lot I found out that nobody using this option and there is a good reason for it, I can just delete the subnode I want to create prior to its creation, In the case that it already exists it will be deleted and in the case that it doesn't exist it will do nothing - So I will be able to create it later on.

    So this is the final script:

        #!/bin/bash
        LOCK_BRANCH="66.66.66" 
        #Delete subnode $LOCK_BRANCH if already exist
        xmlstarlet ed -L -d  "/configurations/rules/rule[name='$LOCK_BRANCH']" config.xml
        #Adding a new subnode to certain nodes
        xmlstarlet ed -L --subnode  "/configurations/rules" --type elem -n rule config.xml
    
        #Adding text to the new node
        xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n name -v "$LOCK_BRANCH" config.xml
        xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n repo -v "mqm" config.xml
        xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n branch -v "refs/heads/12.55.99" config.xml
        xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n emailTo -v "imichael@gmail.com" config.xml
        xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n path -v "Server/.*/schema/v.*/.*/.*-dbSchemaDescriptor\.xml,Server/.*/resources/" config.xml