community.general
community.general copied to clipboard
xml add_children cant add <a href="foo">bar</a> using yaml
Summary
I can't find a way to add the xml node4 in the question of the example:
- hosts: localhost
gather_facts: no
vars:
ansible_python_interpreter: /usr/bin/python3
tasks:
- name: Creating xml file
copy:
dest: out.xml
content: |-
<?xml version='1.0' encoding='UTF-8'?>
<root>
</root>
- xml:
path: out.xml
xpath: /root
add_children:
- node:
attribute: attribute_text
_:
- sub_node:
- node2: node2_text
- node3: "1" # Only strings are valid
# How to add here <node4 attribute="attribute_text">node4_text</node4> in yaml?
# Analogous to: <a href="foo">bar</a>
Is is possible? Is it documented?
Issue Type
Feature Request
Component Name
xml
Ansible Version
$ ansible --version
ansible 2.10.5
config file = /home/user/.ansible.cfg
configured module search path = ['~/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /var/lib/ansible/venv/lib/python3.8/site-packages/ansible
executable location = /var/lib/ansible/venv/bin/ansible
python version = 3.8.9 (default, Apr 6 2021, 00:00:00) [GCC 10.2.1 20201125 (Red Hat 10.2.1-9)]
Configuration
$ ansible-config dump --only-changed
ANSIBLE_PIPELINING(/home/user/.ansible.cfg) = True
ANSIBLE_SSH_ARGS(/home/user/.ansible.cfg) = -F /home/user/.ssh/config -o ControlMaster=auto -o ControlPersist=30m
ANSIBLE_SSH_CONTROL_PATH(/home/user/.ansible.cfg) = ~/.ssh/master-%%r@%%h:%%p
CACHE_PLUGIN(/home/user/.ansible.cfg) = memory
DEFAULT_ACTION_PLUGIN_PATH(/home/user/.ansible.cfg) = ['/home/user/.ansible/plugins/action_plugins']
DEFAULT_CALLBACK_PLUGIN_PATH(/home/user/.ansible.cfg) = ['/home/user/.ansible/plugins/callback_plugins']
DEFAULT_CONNECTION_PLUGIN_PATH(/home/user/.ansible.cfg) = ['/home/user/.ansible/plugins/connection_plugins']
DEFAULT_FILTER_PLUGIN_PATH(/home/user/.ansible.cfg) = ['/home/user/.ansible/plugins/filter_plugins']
DEFAULT_FORKS(/home/user/.ansible.cfg) = 10
DEFAULT_GATHERING(/home/user/.ansible.cfg) = implicit
DEFAULT_HOST_LIST(/home/user/.ansible.cfg) = ['/home/user/.ansible/inventory']
DEFAULT_JINJA2_EXTENSIONS(/home/user/.ansible.cfg) = jinja2.ext.do, jinja2.ext.i18n, jinja2.ext.loopcontrols
DEFAULT_JINJA2_NATIVE(/home/user/.ansible.cfg) = False
DEFAULT_LOG_PATH(/home/user/.ansible.cfg) = /home/user/.ansible/log/ansible.log
DEFAULT_LOOKUP_PLUGIN_PATH(/home/user/.ansible.cfg) = ['/home/user/.ansible/plugins/lookup_plugins']
DEFAULT_MANAGED_STR(/home/user/.ansible.cfg) = Ansible managed. Don't modify it directly.
DEFAULT_POLL_INTERVAL(/home/user/.ansible.cfg) = 15
DEFAULT_ROLES_PATH(/home/user/.ansible.cfg) = ['/home/user/srv/ansible/roles']
DEFAULT_TIMEOUT(/home/user/.ansible.cfg) = 60
DEFAULT_TRANSPORT(/home/user/.ansible.cfg) = smart
DEFAULT_VARS_PLUGIN_PATH(/home/user/.ansible.cfg) = ['/home/user/.ansible/plugins/vars_plugins']
HOST_KEY_CHECKING(/home/user/.ansible.cfg) = False
INJECT_FACTS_AS_VARS(/home/user/.ansible.cfg) = False
INVENTORY_ENABLED(/home/user/.ansible.cfg) = ['host_list', 'script', 'yaml', 'ini']
OS / Environment
$ inxi --system --filter
System: Kernel: 5.11.16-100.fc32.x86_64 x86_64 bits: 64 Desktop: MATE 1.24.2
Distro: Fedora release 32 (Thirty Two)
Steps to Reproduce
- hosts: localhost
gather_facts: no
vars:
ansible_python_interpreter: /usr/bin/python3
tasks:
- name: Creating xml file
copy:
dest: out.xml
content: |-
<?xml version='1.0' encoding='UTF-8'?>
<root>
</root>
- xml:
path: out.xml
xpath: /root
add_children:
- node:
attribute: attribute_text
_:
- sub_node:
- node2: node2_text
- node3: "1" # Only strings are valid
# How to add here <node4 attribute="attribute_text">node4_text</node4> in yaml?
# Analogous to: <a href="foo">bar</a>
# My best try:
- node4:
attribute: attribute_text
_:
- ~: node4_text
Expected Results
Output file:
<?xml version='1.0' encoding='UTF-8'?>
<root>
<node attribute="attribute_text">
<sub_node/>
</node>
<node2>node2_text</node2>
<node3>1</node3>
<node4 attribute="attribute_text">
node4_text
</node4>
</root>
Actual Results
Output file:
<?xml version='1.0' encoding='UTF-8'?>
<root>
<node attribute="attribute_text">
<sub_node/>
</node>
<node2>node2_text</node2>
<node3>1</node3>
<node4 attribute="attribute_text">
<null>node4_text</null>
</node4>
</root>
Code of Conduct
- [x] I agree to follow the Ansible Code of Conduct
Files identified in the description:
If these files are inaccurate, please update the component name
section of the description or use the !component
bot command.
cc @cmprescott @dagwieers @sm4rk0 @tbielawa click here for bot help
@Daniel-Sanchez-Fabregas has this been resolved by #2371?
The example in #2371:
- name: Adding building nodes with floor subnodes from a YAML variable
community.general.xml:
path: /foo/bar.xml
xpath: /business
add_children:
- building:
# Attributes
name: Scumm bar
location: Monkey island
# Subnodes
_:
- floor: Pirate hall
- floor: Grog storage
- construction_date: "1990" # Only strings are valid
- building: Grog factory
The xml task creates:
<business>
...
<building name="Scumm bar" location="Monkey island">
<floor>Pirate hall</floor>
<floor>Grog storage</floor>
<construction_date>1990</construction_date>
</building>
<business>
But, if you try to add a node like:
<a href: "http://127.0.0.1">localhost<a>
in the same way as the example:
- xml:
path: /foo/bar.xml
xpath: /business
add_children:
- a:
href: "http://127.0.0.1"
_: localhost
It fails:
TASK [xml] ***********************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Invalid children type: <class 'str'>, must be list."}
What you are trying to do is not supported by the module.
If someone is interested in implementing this: it probably needs another special key similar to _
at https://github.com/ansible-collections/community.general/blob/main/plugins/modules/files/xml.py#L729
needs_contributor
Files identified in the description:
If these files are incorrect, please update the component name
section of the description or use the !component
bot command.
Hello,
Has anyone found a solution?