Using the Ansible module community.general.xml
, I am attempting to add a child node to the following XML data: (saved into namespace-test.xml)
<configuration xmlns="urn:activemq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
<core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq:core ">
</core>
</configuration>
The data I would like to add, under the core
node, is:
<xi:include href="/conf/xmlconfig-to-include.xml"/>
The Ansible task I am running is:
- name: include modular XML configuration file
community.general.xml:
path: namespace-test.xml
xpath: /conf:configuration/core:core
input_type: xml
add_children:
- '<xi:include href="/conf/xmlconfig-to-include.xml"/>'
namespaces:
conf: urn:activemq
core: urn:activemq:core
xi: "http://www.w3.org/2001/XInclude"
pretty_print: yes
I am expecting to get this result:
<configuration xmlns="urn:activemq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
<core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq:core ">
<xi:include href="/conf/xmlconfig-to-include.xml"/>
</core>
</configuration>
But I am getting the following error message, instead:
Error while parsing child element: Namespace prefix xi on include is not defined
More information after the very usefull options suggested by β.εηοιτ.βε.
The idempotent option did not meet the additionnal requirements (non-specified initially) that I need more than one include in the XML block.
This is really what I was aiming for:
<configuration xmlns="urn:activemq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
<core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq:core ">
<xi:include href="/conf/addresses.xml"/>
<xi:include href="/conf/address-settings.xml"/>
<xi:include href="/conf/security-settings.xml"/>
</core>
</configuration>
There are really two approaches for your issue at hand:
xpath
with the node you are expecting — /conf:configuration/core:core/xi:include
— and just adding the required attribute.add_children
, but in a YAML form, because the XML form does not seems to cope well with namespace reference.Why is the first one highly recommended? Because it makes your task idempotent, so, re-running your playbook won't keep on adding the same node over and over again, if it exists with the right attribute already.
So, here is the idempotent task:
- name: include modular XML configuration file
community.general.xml:
path: namespace-test.xml
xpath: /conf:configuration/core:core/xi:include
attribute: href
value: /conf/xmlconfig-to-include.xml
namespaces:
conf: urn:activemq
core: urn:activemq:core
xi: "http://www.w3.org/2001/XInclude"
pretty_print: yes
Which would give your expected XML.
And regarding the fact that you do need multiple include, the trick, then is to further specialize your xpath expression, for example:
/conf:configuration
/core:core
/xi:include[@href='/conf/xmlconfig-to-include.xml']
So, your task to add the three include nodes could end up in a loop:
- name: include modular XML configuration file
community.general.xml:
path: namespace-test.xml
xpath: /conf:configuration/core:core/xi:include[@href='{{ item }}']
namespaces:
conf: urn:activemq
core: urn:activemq:core
xi: "http://www.w3.org/2001/XInclude"
pretty_print: yes
loop:
- /conf/addresses.xml
- /conf/address-settings.xml
- /conf/security-settings.xml
And if you really want the non-idempotent option, here it is:
- name: include modular XML configuration file
community.general.xml:
path: namespace-test.xml
xpath: /conf:configuration/core:core
add_children:
- "{http://www.w3.org/2001/XInclude}include":
href: /conf/xmlconfig-to-include.xml
namespaces:
conf: urn:activemq
core: urn:activemq:core
xi: "http://www.w3.org/2001/XInclude"
pretty_print: yes