1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

xml module: Implement diff mode (#28592)

This fixes #27952
This commit is contained in:
Dag Wieers 2017-08-24 14:05:13 +02:00 committed by GitHub
parent 3026e5eb15
commit 26d75144b2

View file

@ -94,6 +94,7 @@ options:
requirements: requirements:
- lxml >= 2.3.0 - lxml >= 2.3.0
notes: notes:
- Use the C(--check) and C(--diff) options when testing your expressions.
- This module does not handle complicated xpath expressions, so limit xpath selectors to simple expressions. - This module does not handle complicated xpath expressions, so limit xpath selectors to simple expressions.
- Beware that in case your XML elements are namespaced, you need to use the C(namespaces) parameter. - Beware that in case your XML elements are namespaced, you need to use the C(namespaces) parameter.
- Namespaces prefix should be used for all children of an element where namespace is defined, unless another namespace is defined for them. - Namespaces prefix should be used for all children of an element where namespace is defined, unless another namespace is defined for them.
@ -216,13 +217,13 @@ import re
import traceback import traceback
from collections import MutableMapping from collections import MutableMapping
import copy
from distutils.version import LooseVersion from distutils.version import LooseVersion
from io import BytesIO from io import BytesIO
HAS_LXML = True
try: try:
from lxml import etree from lxml import etree
HAS_LXML = True
except ImportError: except ImportError:
HAS_LXML = False HAS_LXML = False
@ -621,19 +622,29 @@ def children_to_nodes(module=None, children=[], type='yaml'):
def finish(module, tree, xpath, namespaces, changed=False, msg="", hitcount=0, matches=tuple()): def finish(module, tree, xpath, namespaces, changed=False, msg="", hitcount=0, matches=tuple()):
actions = dict(xpath=xpath, namespaces=namespaces, state=module.params['state'])
if not changed: result = dict(
module.exit_json(changed=changed, actions=actions, msg=msg, count=hitcount, matches=matches) actions=dict(xpath=xpath, namespaces=namespaces, state=module.params['state']),
changed=changed,
count=hitcount,
matches=matches,
msg=msg,
)
if changed and module._diff:
result['diff'] = dict(
before=etree.tostring(orig_doc, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print']),
after=etree.tostring(tree, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print']),
)
if module.params['path']: if module.params['path']:
if not module.check_mode: if not module.check_mode:
tree.write(module.params['path'], xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print']) tree.write(module.params['path'], xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print'])
module.exit_json(changed=changed, actions=actions, msg=msg, count=hitcount, matches=matches)
if module.params['xmlstring']: if module.params['xmlstring']:
xml_string = etree.tostring(tree, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print']) result['xmlstring'] = etree.tostring(tree, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print'])
module.exit_json(changed=changed, actions=actions, msg=msg, count=hitcount, matches=matches, xmlstring=xml_string)
module.exit_json(**result)
def main(): def main():
@ -704,6 +715,11 @@ def main():
except etree.XMLSyntaxError as e: except etree.XMLSyntaxError as e:
module.fail_json(msg="Error while parsing path: %s" % e) module.fail_json(msg="Error while parsing path: %s" % e)
# Ensure we have the original copy to compare
if module._diff:
global orig_doc
orig_doc = copy.deepcopy(doc)
if print_match: if print_match:
do_print_match(module, doc, xpath, namespaces) do_print_match(module, doc, xpath, namespaces)