Ansible Module xml
External
Internal
Overview
The plugin is named community.general.xml
and it offers functionality aimed at interacting with XML files, using XPath.
Example
<box>
<object name="A" color="red">square</child>
<object name="B" color="green">circle</child>
<object name="C" color="blue">triangle</child>
</box>
- name: XML manipulation
xml:
path: /tmp/test.xml # the file must exist
xpath: /box/object[@name='B']
Module Parameters
path (dest, file)
The path to the file to operate on. The file must exists, otherwise the module will fail, with a message similar to:
The target XML source '...' does not exist.
.
The parameter is required unless xmlstring
is provided.
- name: test
xml:
path: /tmp/test.xml # the file must exist
...
xpath
A valid XPath expression describing the file item(s) to manipulate. Operates on the document root, /, by default.
- name: test
xml:
...
xpath: /box/object[@name='B']
...
⚠️ Important: the attribute values to query on must be quoted. This is correct:
xpath: /box/object[@name='B']
This is not:
xpath: /box/object[@name=B]
and will cause a failure: Xpath /box/object[@name=B] does not reference a node!
.
count
Boolean. Configure the module to provide the xpath match count. By default is turned off.
xmlstring
A string containing in-line XML content on which to operate. This parameter is required, unless path
is given.
pretty_print
A boolean value ("yes", "no") that tells whether to pretty print the content of the generated files. By default, pretty printing is turned off.
backup
Boolean (yes, no). Create a backup file including timestamp information so the original file can be recovered in case the transformation is wrong.
namespaces
print_match
Boolean, by default is turned off. Search for a given XPath and print out any matches. This parameter requires xpath
to be set.
state (ensure)
Used to set or remove an xpath selection. Can be used to update or remove nodes and attributes. String value: 'absent', 'present'. Default value: 'present'.
Examples:
strip_cdata_tags
content: Query with XPath and Specifying what Kind of Result to Provide
Specifies the kind of content we want to get from the matching XPath expression:
xpath
must be set.
attribute
The matches
result key contains a JSON document listing the matching elements and the value of all their attributes. The count
result key contains the number of matching elements.
- name: test
xml:
path: test.xml
xpath: /box/object[@name='B']
content: 'attribute'
register: xpath_result
produces the following xpath_result.matches
:
[
{
"object": {
"color": "green",
"name": "B"
}
}
]
The value of a specific attribute can be displayed with '{{ xpath_result.matches[0].object.color }}'
.
text
The matches
result key contains a JSON document listing the matching elements name and its element text. The count
result key contains the number of matching elements.
- name: test
xml:
path: test.xml
xpath: /box/object[@name='B']
content: 'text'
register: xpath_result
produces the following xpath_result.matches
:
[
{
"object": "circle"
}
]
The value of a specific element can be displayed with '{{ result.matches[0].object }}'
.
Updating Attribute and Element with attribute/value Usage Pattern
attribute
/value
can be used to add, update and delete XML elements and their attributes. Elements can also be deleted using state
. Use the xpath
to match the element(s), use the attribute
element to specify the element whose value must be modified or deleted, and use the value
element to provide the new value (desired state) as a string. Use None to remove the attribute. The update is idempotent. This pattern can be used to update, add and remove elements and attributes.
Updating an attribute:
- name: test
xml:
file: test.xml
xpath: /box/object[@name='B']
attribute: 'color'
value: 'fuchsia'
Removing an attribute: TODO, did not work.
Updating an element:
- name: test
xml:
file: test.xml
xpath: /box/object[@name='B']
value: 'rectangle'
attribute
Specify the name of the attribute to select, as string, when using parameter value
. Do not prepend with '@'. If attribute:
is not specified at all, the module updates the element value.
value
Configuration element useful when updating or deleting XML content. value
represents the desired state of the attribute specified in attribute
. It could be either a string, or to unset a value, the Python None keyword (YAML Equivalent, null).
Elements default to no value (but present). Attributes default to an empty string.
Children Manipulation
Children can be added with add_children
or updated with set_children
:
input_type
"xml" or "yaml": the input type for add_children
, set_children
.
add_children
Add additional child element(s) to the element that matched xpath
. The elements to be added must be given in a list. Each item may be either a string (example: children=ansible
to add an empty <ansible/>
child or a hash where the key is an element name and the value is the element value. xpath
must be set if add_children
is used.
- name: test
xml:
file: test.xml
xpath: /box
pretty_print: true
add_children:
# Add a new <object>rectangle</rectangle> <box> sub-element
- object: rectangle
# Add a new <object>ellipse</rectangle> <box> sub-element
- object: ellipse
This will modify the file and add the following content:
<box>
...
<object>rectangle</object><object>ellipse</object></box>
The output is not "pretty printed", to pretty print, use pretty_print: yes
For this syntax:
add_children:
- object: ""
we get:
<box>
...
<object></object>
For this syntax:
add_children:
- object: # nothing else
we get:
<box>
...
<object/>
For more complex examples of how to add elements with attributes and recursive elements, see:
- Add Elements with Values
- Add an Element with Attributes
- Add an Element with Attributes and Value
- Add a Complex, Hierarchical Element
set_children
Set the child element(s) of a selected element for a given xpath. Removes any existing children. Child elements must be specified as in add_children.
insertbefore
Add additional child element(s) before the first selected element for a given xpath. Child elements must be given in a list and each item may be either a string (eg. children=ansible to add an empty <ansible/> child element), or a hash where the key is an element name and the value is the element value. This parameter requires xpath to be set.
insertafter
Add additional child element(s) after the last selected element for a given xpath. Child elements must be given in a list and each item may be either a string (eg. children=ansible to add an empty <ansible/> child element), or a hash where the key is an element name and the value is the element value. This parameter requires xpath to be set.
Playground
Use Cases
Add Elements with Values
- name: test
xml:
file: test.xml
xpath: /box
pretty_print: true
add_children:
- object: 'rectangle'
- object: 'ellipsis'
adds:
<box>
...
<object>rectangle</object>
<object>ellipsis</object>
</box>
Add an Element with Attributes
- name: test
xml:
file: test.xml
xpath: /box
pretty_print: true
add_children:
- object:
name: 'D'
color: 'yellow'
adds:
<box>
...
<object name="D" color="yellow"/>
</box>
Add an Element with Attributes and Value
There is no obvious way to add an element that has specific attributes and a specific value in one operation. This is how it's done in two operations: add the element with attributes and then update it with the correct value.
- name: Add an element with the required attributes
xml:
file: test.xml
xpath: /box
pretty_print: true
add_children:
- object:
name: 'D'
color: 'yellow'
- name: Update added element with the correct value
xml:
file: test.xml
xpath: /box/object[@name='D' and @color='yellow']
value: 'rectangle'
adds:
<box>
...
<object name="D" color="yellow">rectangle</object>
</box>
Add a Complex, Hierarchical Element
- name: test playbook
hosts: localhost
tasks:
- name: test
xml:
file: /Users/ovidiu/tmp/jdk.table.2.xml
xpath: /application/component[@name='ProjectJdkTable']
pretty_print: true
add_children:
- jdk:
# <jdk> attributes
version: "2"
# <jdk> sub-nodes <name>, <type>, ... <roots>
_:
- name:
value: "corretto-12"
- type:
value: "JavaSDK"
- version:
value: "Amazon Corretto version 12.0.77"
- homePath:
value: "/Library/Java/JavaVirtualMachines/amazon-corretto-12.jdk/Contents/Home"
- roots:
# <roots> sub-nodes <annotationPath>, <classPath>, ...
_:
- annotationsPath:
# <annotationsPath> sub-node <root>
_:
- root:
# <root> attributes
type: "composite"
# <root> sub-nodes <root>
_:
- root:
# <root> attributes
url: "jar://$APPLICATION_HOME_DIR$/plugins/java/lib/jdkAnnotations.jar!/"
type: "simple"
- classPath:
_:
- root:
type: "composite"
_:
- root:
url: "jrt:///Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home!/java.base"
type: "simple"
- root:
url: "jrt:///Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home!/java.compiler"
type: "simple"
- javadocPath:
_:
- root:
type: "composite"
- sourcePath:
_:
- root:
type: "composite"
_:
- root:
url: "jar:///Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home/lib/src.zip!/java.se"
type: "simple"
- root:
url: "jar:///Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home/lib/src.zip!/jdk.aot"
type: "simple"
- additional:
produces:
<?xml version='1.0' encoding='UTF-8'?>
<application>
<component name="ProjectJdkTable">
<jdk version="2">
<name value="corretto-12"/>
<type value="JavaSDK"/>
<version value="Amazon Corretto version 12.0.77"/>
<homePath value="/Library/Java/JavaVirtualMachines/amazon-corretto-12.jdk/Contents/Home"/>
<roots>
<annotationsPath>
<root type="composite">
<root url="jar://$APPLICATION_HOME_DIR$/plugins/java/lib/jdkAnnotations.jar!/" type="simple"/>
</root>
</annotationsPath>
<classPath>
<root type="composite">
<root url="jrt:///Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home!/java.base" type="simple"/>
<root url="jrt:///Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home!/java.compiler" type="simple"/>
</root>
</classPath>
<javadocPath>
<root type="composite"/>
</javadocPath>
<sourcePath>
<root type="composite">
<root url="jar:///Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home/lib/src.zip!/java.se" type="simple"/>
<root url="jar:///Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home/lib/src.zip!/jdk.aot" type="simple"/>
</root>
</sourcePath>
</roots>
<additional/>
</jdk>
</component>
</application>
Update an Attribute
- name: test
xml:
file: test.xml
xpath: /box/object[@name='B']
attribute: 'color'
value: 'fuchsia'
Also see "Updating Attributes and Elements with attribute/value Usage Pattern" above.
Update the Value of an Element
- name: test
xml:
path: "{{idea_path}}/.idea/compiler.xml"
xpath: /box/object[@name='B']
value: "hexagon"
Remove an Attribute with state
Remove the 'color' attribute from matching elements.
- name: test
xml:
file: /Users/ovidiu/tmp/test.xml
xpath: /box/object[@name='B']/@color
state: 'absent'
Also see state
above.
Remove an Element with state
Remove the 'color' attribute from matching elements.
- name: test
xml:
file: /Users/ovidiu/tmp/test.xml
xpath: /box/object[@name='B']
state: 'absent'
To remove the parent element, add "/.." to the XPath.
Also see state
above.