21 from lxml
import etree
as lxml_etree
32 should_be_equal = asserts.assert_equal
454 ROBOT_LIBRARY_SCOPE =
'GLOBAL'
459 _xml_declaration = re.compile(
'^<\?xml .*\?>')
475 if use_lxml
and lxml_etree:
483 if use_lxml
and not lxml_etree:
484 logger.warn(
'XML library reverted to use standard ElementTree '
485 'because lxml module is not installed.')
519 def parse_xml(self, source, keep_clark_notation=False, strip_namespaces=False):
520 with ETSource(source)
as source:
521 tree = self.
etreeetree.parse(source)
523 strip = (lxml_etree.Comment, lxml_etree.ProcessingInstruction)
524 lxml_etree.strip_elements(tree, *strip, **
dict(with_tail=
False))
525 root = tree.getroot()
557 if len(elements) != 1:
568 return "No element matching '%s' found." % xpath
570 return "One element matching '%s' found." % xpath
571 return "Multiple elements (%d) matching '%s' found." % (count, xpath)
593 return finder.find_all(source, xpath)
611 return list(self.
get_elementget_element(source, xpath))
621 count = len(self.
get_elementsget_elements(source, xpath))
622 logger.info(
"%d element%s matched '%s'." % (count, s(count), xpath))
686 element = self.
get_elementget_element(source, xpath)
695 for child
in element:
696 for text
in self.
_yield_texts_yield_texts(child, top=
False):
698 if element.tail
and not top:
702 return ' '.join(text.split())
721 return [self.
get_element_textget_element_text(elem, normalize_whitespace=normalize_whitespace)
722 for elem
in self.
get_elementsget_elements(source, xpath)]
747 normalize_whitespace=False, message=None):
748 text = self.
get_element_textget_element_text(source, xpath, normalize_whitespace)
767 normalize_whitespace=False, message=None):
768 text = self.
get_element_textget_element_text(source, xpath, normalize_whitespace)
791 return self.
get_elementget_element(source, xpath).get(name, default)
879 "has value '%s'." % (name, attr))
917 normalize_whitespace=False):
919 exclude_children, normalize_whitespace)
938 normalize_whitespace=False):
940 exclude_children, normalize_whitespace)
943 normalize_whitespace):
945 if is_truthy(normalize_whitespace)
else None
968 self.
get_elementget_element(source, xpath).tag = tag
977 for elem
in self.
get_elementsget_elements(source, xpath):
1004 element = self.
get_elementget_element(source, xpath)
1005 if text
is not None:
1007 if tail
is not None:
1017 for elem
in self.
get_elementsget_elements(source, xpath):
1042 raise RuntimeError(
'Attribute name can not be empty.')
1044 self.
get_elementget_element(source, xpath).attrib[name] = value
1053 for elem
in self.
get_elementsget_elements(source, xpath):
1076 attrib = self.
get_elementget_element(source, xpath).attrib
1087 for elem
in self.
get_elementsget_elements(source, xpath):
1109 self.
get_elementget_element(source, xpath).attrib.clear()
1118 for elem
in self.
get_elementsget_elements(source, xpath):
1149 parent = self.
get_elementget_element(source, xpath)
1152 parent.append(element)
1154 parent.insert(
int(index), element)
1203 for element
in self.
get_elementsget_elements(source, xpath):
1211 parent.remove(element)
1214 for parent
in root.getiterator():
1215 for child
in parent:
1216 if child
is element:
1218 raise RuntimeError(
'Cannot remove root element.')
1221 if not element.tail:
1223 index = list(parent).index(element)
1225 parent.text = (parent.text
or '') + element.tail
1227 sibling = parent[index-1]
1228 sibling.tail = (sibling.tail
or '') + element.tail
1256 element = self.
get_elementget_element(source, xpath)
1282 return copy.deepcopy(self.
get_elementget_element(source, xpath))
1297 source = self.
get_elementget_element(source, xpath)
1298 string = self.
etreeetree.tostring(source, encoding=
'UTF-8').decode(
'UTF-8')
1301 string = string.encode(encoding)
1314 logger.write(string, level)
1337 path = os.path.abspath(path.replace(
'/', os.sep))
1339 tree = self.
etreeetree.ElementTree(elem)
1340 config = {
'encoding': encoding}
1342 config[
'xml_declaration'] =
True
1346 if tree.docinfo.doctype:
1347 config[
'doctype'] = tree.docinfo.doctype
1348 tree = self.
etreeetree.ElementTree(elem)
1349 with open(path,
'wb')
as output:
1350 if 'doctype' in config:
1351 output.write(self.
etreeetree.tostring(tree, **config))
1353 tree.write(output, **config)
1354 logger.info(
'XML saved to <a href="file://%s">%s</a>.' % (path, path),
1380 raise RuntimeError(
"'Evaluate Xpath' keyword only works in lxml mode.")
1381 return self.
get_elementget_element(source, context).xpath(expression)
1390 def strip(self, elem, preserve=True, current_ns=None, top=True):
1391 if elem.tag.startswith(
'{')
and '}' in elem.tag:
1392 ns, elem.tag = elem.tag[1:].split(
'}', 1)
1393 if preserve
and ns != current_ns:
1394 elem.attrib[
'xmlns'] = ns
1397 elem.attrib[
'xmlns'] =
''
1400 self.
stripstrip(child, preserve, current_ns, top=
False)
1401 if top
and not preserve
and self.
lxml_treelxml_tree:
1402 self.
etreeetree.cleanup_namespaces(elem)
1404 def unstrip(self, elem, current_ns=None, copied=False):
1406 elem = copy.deepcopy(elem)
1407 ns = elem.attrib.pop(
'xmlns', current_ns)
1409 elem.tag =
'{%s}%s' % (ns, elem.tag)
1411 self.
unstripunstrip(child, ns, copied=
True)
1426 if not self.
lxmllxml:
1427 return elem.findall(xpath)
1428 finder = self.
etreeetree.ETXPath(xpath)
1433 raise RuntimeError(
'No xpath given.')
1438 except UnicodeError:
1439 if not xpath.replace(
'/',
'').isalnum():
1440 logger.warn(
'XPATHs containing non-ASCII characters and '
1441 'other than tag names do not always work with '
1442 'Python versions prior to 2.7. Verify results '
1443 'manually and consider upgrading to 2.7.')
1449 def __init__(self, comparator, normalizer=None, exclude_children=False):
1454 def compare(self, actual, expected, location=None):
1460 if location.is_not_root:
1466 self.
_compare_compare(actual.tag, expected.tag,
'Different tag name', location,
1469 def _compare(self, actual, expected, message, location, comparator=None):
1470 if location.is_not_root:
1471 message =
"%s at '%s'" % (message, location.path)
1474 comparator(actual, expected, message)
1477 self.
_compare_compare(sorted(actual.attrib), sorted(expected.attrib),
1478 'Different attribute names', location, should_be_equal)
1479 for key
in actual.attrib:
1480 self.
_compare_compare(actual.attrib[key], expected.attrib[key],
1481 "Different value for attribute '%s'" % key, location)
1485 'Different text', location)
1492 'Different tail text', location)
1495 self.
_compare_compare(len(actual), len(expected),
'Different number of child elements',
1496 location, should_be_equal)
1497 for act, exp
in zip(actual, expected):
1498 self.
comparecompare(act, exp, location.child(act.tag))
1513 tag +=
'[%d]' % self.
_children_children[tag]
1514 return Location(
'%s/%s' % (self.
pathpath, tag), is_root=
False)
An always available standard library with often needed keywords.
def __init__(self, comparator, normalizer=None, exclude_children=False)
def _compare_texts(self, actual, expected, location)
def _compare_tails(self, actual, expected, location)
def compare(self, actual, expected, location=None)
def _compare_children(self, actual, expected, location)
def _compare(self, actual, expected, message, location, comparator=None)
def _compare_tags(self, actual, expected, location)
def _compare_attributes(self, actual, expected, location)
def find_all(self, elem, xpath)
def __init__(self, etree, modern=True, lxml=False)
def _get_xpath(self, xpath)
def __init__(self, path, is_root=True)
def strip(self, elem, preserve=True, current_ns=None, top=True)
def __init__(self, etree, lxml_etree=False)
def unstrip(self, elem, current_ns=None, copied=False)
Robot Framework test library for verifying and modifying XML documents.
def remove_element_attribute(self, source, name, xpath='.')
Removes attribute name from the specified element.
def set_elements_text(self, source, text=None, tail=None, xpath='.')
Sets text and/or tail text of the specified elements.
def remove_element_attributes(self, source, xpath='.')
Removes all attributes from the specified element.
def _compare_elements(self, source, expected, comparator, exclude_children, normalize_whitespace)
def save_xml(self, source, path, encoding='UTF-8')
Saves the given element to the specified file.
def element_should_exist(self, source, xpath='.', message=None)
Verifies that one or more element match the given xpath.
def _raise_wrong_number_of_matches(self, count, xpath, message=None)
def elements_should_match(self, source, expected, exclude_children=False, normalize_whitespace=False)
Verifies that the given source element matches expected.
def set_element_attribute(self, source, name, value, xpath='.')
Sets attribute name of the specified element to value.
def element_attribute_should_be(self, source, name, expected, xpath='.', message=None)
Verifies that the specified attribute is expected.
def elements_should_be_equal(self, source, expected, exclude_children=False, normalize_whitespace=False)
Verifies that the given source element is equal to expected.
def set_elements_tag(self, source, tag, xpath='.')
Sets the tag of the specified elements.
def _wrong_number_of_matches(self, count, xpath)
def element_should_not_exist(self, source, xpath='.', message=None)
Verifies that no element match the given xpath.
def set_elements_attribute(self, source, name, value, xpath='.')
Sets attribute name of the specified elements to value.
def get_child_elements(self, source, xpath='.')
Returns the child elements of the specified element as a list.
def __init__(self, use_lxml=False)
Import library with optionally lxml mode enabled.
def element_to_string(self, source, xpath='.', encoding=None)
Returns the string representation of the specified element.
def get_elements(self, source, xpath)
Returns a list of elements in the source matching the xpath.
def _preserve_tail(self, element, parent)
def log_element(self, source, level='INFO', xpath='.')
Logs the string representation of the specified element.
def _find_parent(self, root, element)
def evaluate_xpath(self, source, expression, context='.')
Evaluates the given xpath expression and returns results.
def get_elements_texts(self, source, xpath, normalize_whitespace=False)
Returns text of all elements matching xpath as a list.
def _normalize_whitespace(self, text)
def get_element_attributes(self, source, xpath='.')
Returns all attributes of the specified element.
def add_element(self, source, element, index=None, xpath='.')
Adds a child element to the specified element.
def parse_xml(self, source, keep_clark_notation=False, strip_namespaces=False)
Parses the given XML file or string into an element structure.
def get_element_text(self, source, xpath='.', normalize_whitespace=False)
Returns all text of the element, possibly whitespace normalized.
def _remove_element(self, root, element, remove_tail=False)
def get_element_attribute(self, source, name, xpath='.', default=None)
Returns the named attribute of the specified element.
def remove_elements_attributes(self, source, xpath='.')
Removes all attributes from the specified elements.
def element_should_not_have_attribute(self, source, name, xpath='.', message=None)
Verifies that the specified element does not have attribute name.
def remove_elements(self, source, xpath='', remove_tail=False)
Removes all elements matching xpath from the source structure.
def element_text_should_be(self, source, expected, xpath='.', normalize_whitespace=False, message=None)
Verifies that the text of the specified element is expected.
def remove_elements_attribute(self, source, name, xpath='.')
Removes attribute name from the specified elements.
def set_element_text(self, source, text=None, tail=None, xpath='.')
Sets text and/or tail text of the specified element.
def _yield_texts(self, element, top=True)
def element_text_should_match(self, source, pattern, xpath='.', normalize_whitespace=False, message=None)
Verifies that the text of the specified element matches expected.
def set_element_tag(self, source, tag, xpath='.')
Sets the tag of the specified element.
def get_element(self, source, xpath='.')
Returns an element in the source matching the xpath.
def clear_element(self, source, xpath='.', clear_tail=False)
Clears the contents of the specified element.
def get_element_count(self, source, xpath='.')
Returns and logs how many elements the given xpath matches.
def copy_element(self, source, xpath='.')
Returns a copy of the specified element.
def remove_element(self, source, xpath='', remove_tail=False)
Removes the element matching xpath from the source structure.
def element_attribute_should_match(self, source, name, pattern, xpath='.', message=None)
Verifies that the specified attribute matches expected.
def is_truthy(item)
Returns True or False depending is the item considered true or not.
def is_falsy(item)
Opposite of :func:is_truthy.
def get_version(naked=False)