user2816863
user2816863

Reputation: 37

Adding new nodes to XML file with Augeas

I have this XML file /opt/webapp/config.xml for a custom webapp that contains a parent node items.

<items>
</items>

I'm trying to add a list of new child nodes item with an attribute value while making sure the child node doesn't contain the end/closing tag because the app requires that format.

<items>
<item value="video/*"/><item value="audio/*"/><item value="application/rar"/><item value="application/x-zip"/><item value="application/x-gzip"/>
</items>

If I were to open up the existing configuration using augtool, I will get the below output.

/files/opt/webapp/config.xml/File/FileTypes
/files/opt/webapp/config.xml/File/FileTypes/#text = "\n"
/files/opt/webapp/config.xml/File/FileTypes/items
/files/opt/webapp/config.xml/File/FileTypes/items/#text = "\n"
/files/opt/webapp/config.xml/File/FileTypes/items/item[1] = "#empty"
/files/opt/webapp/config.xml/File/FileTypes/items/item[1]/#attribute
/files/opt/webapp/config.xml/File/FileTypes/items/item[1]/#attribute/value = "video/*"
/files/opt/webapp/config.xml/File/FileTypes/items/item[2] = "#empty"
/files/opt/webapp/config.xml/File/FileTypes/items/item[2]/#attribute
/files/opt/webapp/config.xml/File/FileTypes/items/item[2]/#attribute/value = "audio/*"
/files/opt/webapp/config.xml/File/FileTypes/items/item[3] = "#empty"
/files/opt/webapp/config.xml/File/FileTypes/items/item[3]/#attribute
/files/opt/webapp/config.xml/File/FileTypes/items/item[3]/#attribute/value = "application/rar"

I found a few posts here and here discussing about xml and Augeas but those examples follow the format with both starting and closing tag. For example: <item value="application/rar"></item>. And I'm trying to find a way to see if Augeas can also create and add child node with a self-closing tag only.

I'm using augtool (version 1.10.1) that comes with puppet agent 5.5.10 on RHEL 7.

Thank you.

Upvotes: 1

Views: 442

Answers (1)

raphink
raphink

Reputation: 3665

As you can see in your example, self-closing tags have a value of #empty, so you just need to set that value on your items.

So in your case, you could do something like:

# set context to use relative paths later
set /augeas/context /files/opt/webapp/config.xml/File/FileTypes/items

# define a $video variable pointing to the video element, define it as self-closing
defnode video item[#attribute/value="video/*"] "#empty"
# Set element value
set $video/#attribute/value "video/*"

defnode audio item[#attribute/value="audio/*"] "#empty"
set $audio/#attribute/value "audio/*"

defnode rar item[#attribute/value="application/rar"] "#empty"
set $rar/#attribute/value "application/rar"

etc.

resulting in:

<items>
<item value="video/*"/>
<item value="audio/*"/>
<item value="application/rar"/>
</items>

defnode will define a variable that points to a node and set its value if it doesn't exist yet. As a result, this code will be idempotent.

Upvotes: 1

Related Questions