85 lines
2.5 KiB
Python
85 lines
2.5 KiB
Python
# Copyright 2016 Mirantis, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
from xml.dom import minidom
|
|
|
|
from lxml import etree # nosec # We are authors of this XML
|
|
|
|
import six
|
|
|
|
|
|
class XMLGeneratorElement(object):
|
|
|
|
def __init__(self, name, parent, builder):
|
|
# pylint: disable=no-member
|
|
self.elem = etree.SubElement(parent, name)
|
|
# pylint: enable=no-member
|
|
self.parent = parent
|
|
self.builder = builder
|
|
self.prev_elem = None
|
|
|
|
def __enter__(self):
|
|
self.prev_elem = self.builder.curr_el
|
|
self.builder.curr_el = self.elem
|
|
|
|
def __exit__(self, *args):
|
|
self.builder.curr_el = self.prev_elem
|
|
self.prev_elem = None
|
|
|
|
def __getattr__(self, name):
|
|
return XMLGeneratorElement(
|
|
name=name,
|
|
parent=self.elem,
|
|
builder=self.builder)
|
|
|
|
def __call__(self, txt=None, **kwargs):
|
|
# update attributes
|
|
kwargs = {k: str(v) for k, v in kwargs.items()}
|
|
self.elem.attrib.update(kwargs)
|
|
|
|
# update text if any
|
|
if txt:
|
|
self.elem.text = str(txt)
|
|
|
|
return self
|
|
|
|
|
|
@six.python_2_unicode_compatible
|
|
class XMLGenerator(object):
|
|
|
|
def __init__(self, root_name, **kwargs):
|
|
# pylint: disable=no-member
|
|
self.root = etree.Element(root_name)
|
|
# pylint: enable=no-member
|
|
kwargs = {k: str(v) for k, v in kwargs.items()}
|
|
self.root.attrib.update(kwargs)
|
|
self.curr_el = self.root
|
|
|
|
def __getattr__(self, name):
|
|
return XMLGeneratorElement(
|
|
name=name,
|
|
parent=self.curr_el,
|
|
builder=self)
|
|
|
|
def __str__(self):
|
|
# pylint: disable=no-member
|
|
rough_string = etree.tostring(self.root, encoding='utf-8')
|
|
# pylint: enable=no-member
|
|
reparsed = minidom.parseString(rough_string)
|
|
s = reparsed.toprettyxml(indent=' ', encoding='utf-8')
|
|
if six.PY2:
|
|
return s
|
|
else:
|
|
return str(s, encoding='utf-8')
|