0
votes

I need to be able to add strings (paths) to an XML file using shell script, This is the XML that I have:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<configurations>
    <smtpHost>smtp3.gmail.com</smtpHost>
    <smtpPort>25</smtpPort>
    <emailFrom>[email protected]</emailFrom>
    <emailSubject>Push notification</emailSubject>
    <!-- Stash general URL-->
    <gitViewerURL>http://server0005.gmail.net:7990/projects/</gitViewerURL>
    <rule>
        <name>test_12.55.4</name>
        <repo>test</repo>
        <branch>refs/heads/12.55.4</branch>
        <emailTo>[email protected]</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>[email protected]</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>[email protected]</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>
</configurations>

And I need to add additional path to the subnode only for one version (let's say for test_12.55.10), The path's I want to add are:

Server/./resources/schema/v12_55_10/./.-dbSchemaDescriptor.xml, Server/./resources/SpringIOC/dataupgrader/v12_55_10/./.-dataUpgrader.xml, Server/./java/com/hp/mqm/dataupgrader/v12_55_10/./..java, Server/./resources/indexes/v12_55_10/.*.index

I want to use sed or "xmlstarlet" as I saw other people suggested, So the output that I want to get is:

<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,Server/.*/resources/schema/v12_55_10/.*/.*-dbSchemaDescriptor\.xml,
Server/.*/resources/SpringIOC/dataupgrader/v12_55_10/.*/.*-dataUpgrader\.xml,
Server/.*/java/com/hp/mqm/dataupgrader/v12_55_10/.*/.*\.java,
Server/.*/resources/indexes/v12_55_10/.*\.index</path>
2

2 Answers

2
votes

It can be done with sed. Here is a small sed script that should work as long as path follows name in a rule:

script.sed

# filter for block from name to end of rule with the version:
/<name>test_12.55.10<\/name>/,/<\/rule>/ {
    /<\/path>/ {
                # this is a multiline second argument to s:
                s+<\/path>+,\
                    Server/./resources/schema/v12_55_10/./.-dbSchemaDescriptor.xml,\
                    Server/./resources/SpringIOC/dataupgrader/v12_55_10/./.-dataUpgrader.xml,\
                    Server/./java/com/hp/mqm/dataupgrader/v12_55_10/./..java,\
                    Server/./resources/indexes/v12_55_10/.*.index\
                </path>\
                +;
                # remove the whitespaces inserted above for readability
                s/,[ \n]+Server//g;
                }
    };

You use it like this: sed -rf script.sed yourfile.xml.

You might be able to fill the version number and additional paths from a shell script (note the additional backslashes after each Server line).

1
votes

Here's one way you could do it with xmlstarlet like you originally requested...

name="test_12.55.10"
path=", Server/./resources/schema/v12_55_10/./.-dbSchemaDescriptor.xml, Server/./resources/SpringIOC/dataupgrader/v12_55_10/./.-dataUpgrader.xml, Server/./java/com/hp/mqm/dataupgrader/v12_55_10/./..java, Server/./resources/indexes/v12_55_10/.*.index"

xmlstarlet ed -L -a "/*/rule[name='$name']/path/text()" --type text -n "" -v "$path" input.xml

Caution: This will modify the file in place. (because of -L)

This could be a one-liner if you didn't use the variables.