3

My XML :

<?xml version='1.0' encoding='UTF-8'?>
<mm2-moduleset plugin="[email protected]">
..
    <buildType class="hudson.mm.MMModuleSet$Component">
       <viewableName>Component</viewableName>
    </buildType>
    <selectedCodeComponents>
       <string>admin-content</string>
       <string>admin</string>
    </selectedCodeComponents>
    <incrementalBuild>false</incrementalBuild>
    ...
    ...
</mm2-moduleset>

Basically, im trying to get the job details from the jenkins-cli plugin, and update the configuration of the xml file(the configuration of the jenkins job) and then update the jenkins job using shell-script.

For that, I need to replace "string" attribute values of the "selectedCodeComponents" attribute according to the user input using shell script. if the input is check, check-content, bank, then

    <selectedCodeComponents>
       <string>check-content</string>
       <string>check</string>
       <string>bank</string>     
    </selectedCodeComponents>

My code:

${JAVA_HOME}/bin/java -Djavax.net.ssl.trustStore=${JENKINS_HOST}.keystore -Djavax.net.ssl.trustStorePassword=112012 -jar ./jenkins-cli.jar -s https://$USERNAME:$API_TOKEN\@$JENKINS_HOST:$JENKINS_PORT\/jenkins get-job job_1 > job1.xml

(Jenkins-cli - get-job returns configuration in xml file)

I thought of first deleting the string elements in selectedcodecomponents and append with what ever user gives. Like this,

xmlstarlet ed -d "mm2-moduleset/selectedCodeComponents/string" abc.xml

// some logic
xmlstarlet ed -a "mm2-moduleset/selectedCodeComponents/string" --type elem -n string -v "something" abc.xml

But after executing the first command (xmlstarlet ed -d), it deletes the seletedcodecomponents as well. But i wanted to delete only string elements inside it.

<?xml version='1.0' encoding='UTF-8'?>
<mm2-moduleset plugin="[email protected]">
..
  <buildType class="hudson.mm.MMModuleSet$Component">
     <viewableName>Component</viewableName>
  </buildType>
  </selectedCodeComponents>
  <incrementalBuild>false</incrementalBuild>
  ...
  ...
</mm2-moduleset>

append command also appending twice.(xmlstarlet ed -a ) For ex,

xmlstarlet ed -a "mm2-moduleset/selectedCodeComponents/string" --type elem -n string -v "check" abc.xml


<?xml version='1.0' encoding='UTF-8'?>
<mm2-moduleset plugin="[email protected]">
..
    <buildType class="hudson.mm.MMModuleSet$Component">
       <viewableName>Component</viewableName>
    </buildType>
    <selectedCodeComponents>
       <string>admin-content</string>
       <string>check</string>
       <string>admin</string>
       <string>check</string>

    </selectedCodeComponents>
    <incrementalBuild>false</incrementalBuild>
    ...
    ...
</mm2-moduleset>

could you please tell me how to delete only string elements inside selectedcodecomponents element and why append command appends twice

I'm new to shell script hence your suggestions would help me

2 Answers 2

4

Fixing up your sample XML file a bit, to give it a root tag:

$ cat file.xml
<?xml version='1.0' encoding='UTF-8'?>
<root>
    <buildType class="hudson.mm.MMModuleSet$Component">
       <viewableName>Component</viewableName>
    </buildType>
    <selectedCodeComponents>
       <string>admin-content</string>
       <string>admin</string>
    </selectedCodeComponents>
    <incrementalBuild>false</incrementalBuild>
</root>

You delete the string nodes like this

$ xmlstarlet ed -d '//selectedCodeComponents/string' file.xml 
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <buildType class="hudson.mm.MMModuleSet$Component">
    <viewableName>Component</viewableName>
  </buildType>
  <selectedCodeComponents/>
  <incrementalBuild>false</incrementalBuild>
</root>

And then add new string subnodes like this

$ xmlstarlet ed -d '//selectedCodeComponents/string' file.xml |
xmlstarlet ed -s '//selectedCodeComponents' -t elem -n string -v something1 |
xmlstarlet ed -s '//selectedCodeComponents' -t elem -n string -v something2 |
xmlstarlet ed -s '//selectedCodeComponents' -t elem -n string -v something3
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <buildType class="hudson.mm.MMModuleSet$Component">
    <viewableName>Component</viewableName>
  </buildType>
  <selectedCodeComponents>
    <string>something1</string>
    <string>something2</string>
    <string>something3</string>
  </selectedCodeComponents>
  <incrementalBuild>false</incrementalBuild>
</root>
Sign up to request clarification or add additional context in comments.

6 Comments

Hi Jackman, thanks you for your input. but may i know why are u adding root tag?
you haven't specified the xml file in the xmlstarlet subnode command? what is the difference between my code and this code? and im not sure how the output would differ. could u please explain
<?xml ...> is not an element, it's a declaration, so the closing </xml> is invalid -- test with xmlstarlet validate file.xml
Unless you specify otherwise, xmlstarlet prints its output to stdout, so I'm just piping the result from one command to another to build up the final result. You can redirect that into a file (but not the same file!) xmlstarlet file.xml | xmlstarlet | xmlstarlet > file2.xml && mv file2.xml file.xml
oh ok. its the configuration xml file returned by jenkins-cli. i need to update the selected components list. same jenkins-cli will take this xml file to update the configuration of the job. so i fear if i could add root in this. is there any other way to do this?
|
1

1) if you need to delete whole string elements, use below code

xmlstarlet ed -P -S -d "/mm2-moduleset/.../selectedCodeComponents/string" config.xml >temp.xml
mv temp.xml config.xml

2) if you have to delete a particular string element, use below code

read -p "read the string that need to be deleted" deleteString

xmlstarlet ed -P -S -d "/mm2-moduleset/.../selectedCodeComponents/string[text()='$deleteString']" config.xml >temp.xml
mv temp.xml config.xml

3) if you have to replace the strings based on user input, you can try the below code

read - "read the string that need to be modify" modifyString1 modifyString2 modifyString3

xmlstarlet ed -P -S -s "/mm2-moduleset/.../selectedCodeComponents" -t elem -n string -v $modifyString1 -s "/mm2-moduleset/.../selectedCodeComponents" -t elem -n string -v $modifyString2 -s "/mm2-moduleset/.../selectedCodeComponents" -t elem -n string -v $modifyString3 config.xml >temp.xml
mv temp.xml config.xml

1 Comment

You can skip the temporary output file if you pipe to tee instead of using console output redirection: xmlstarlet ed -d //rootnode/subnode /path/to/file | tee /path/to/file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.