Robot Framework
XML.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 import copy
17 import os
18 import re
19 
20 try:
21  from lxml import etree as lxml_etree
22 except ImportError:
23  lxml_etree = None
24 else:
25  # `lxml.etree._Attrib` doesn't extend `Mapping` and thus our `is_dict_like`
26  # doesn't recognize it unless we register it ourselves. Fixed in lxml 4.9.2:
27  # https://bugs.launchpad.net/lxml/+bug/1981760
28  from collections.abc import MutableMapping
29  Attrib = getattr(lxml_etree, '_Attrib', None)
30  if Attrib and not isinstance(Attrib, MutableMapping):
31  MutableMapping.register(Attrib)
32  del Attrib, MutableMapping
33 
34 from robot.api import logger
35 from robot.api.deco import keyword
36 from robot.libraries.BuiltIn import BuiltIn
37 from robot.utils import (asserts, ET, ETSource, is_bytes, is_falsy, is_string,
38  is_truthy, plural_or_not as s)
39 from robot.version import get_version
40 
41 
42 should_be_equal = asserts.assert_equal
43 should_match = BuiltIn().should_match
44 
45 
46 
456 class XML:
457  ROBOT_LIBRARY_SCOPE = 'GLOBAL'
458  ROBOT_LIBRARY_VERSION = get_version()
459 
462  _xml_declaration = re.compile('^<\?xml .*\?>')
463 
464 
476  def __init__(self, use_lxml=False):
477  use_lxml = is_truthy(use_lxml)
478  if use_lxml and lxml_etree:
479  self.etreeetree = lxml_etree
480  self.modern_etreemodern_etree = True
481  self.lxml_etreelxml_etree = True
482  else:
483  self.etreeetree = ET
484  self.modern_etreemodern_etree = ET.VERSION >= '1.3'
485  self.lxml_etreelxml_etree = False
486  if use_lxml and not lxml_etree:
487  logger.warn('XML library reverted to use standard ElementTree '
488  'because lxml module is not installed.')
489  self._ns_stripper_ns_stripper = NameSpaceStripper(self.etreeetree, self.lxml_etreelxml_etree)
490 
491 
521  def parse_xml(self, source, keep_clark_notation=False, strip_namespaces=False):
522  if isinstance(source, os.PathLike):
523  source = str(source)
524  with ETSource(source) as source:
525  tree = self.etreeetree.parse(source)
526  if self.lxml_etreelxml_etree:
527  strip = (lxml_etree.Comment, lxml_etree.ProcessingInstruction)
528  lxml_etree.strip_elements(tree, *strip, **dict(with_tail=False))
529  root = tree.getroot()
530  if not is_truthy(keep_clark_notation):
531  self._ns_stripper_ns_stripper.strip(root, preserve=is_falsy(strip_namespaces))
532  return root
533 
534 
559  def get_element(self, source, xpath='.'):
560  elements = self.get_elementsget_elements(source, xpath)
561  if len(elements) != 1:
562  self._raise_wrong_number_of_matches_raise_wrong_number_of_matches(len(elements), xpath)
563  return elements[0]
564 
565  def _raise_wrong_number_of_matches(self, count, xpath, message=None):
566  if not message:
567  message = self._wrong_number_of_matches_wrong_number_of_matches(count, xpath)
568  raise AssertionError(message)
569 
570  def _wrong_number_of_matches(self, count, xpath):
571  if not count:
572  return "No element matching '%s' found." % xpath
573  if count == 1:
574  return "One element matching '%s' found." % xpath
575  return "Multiple elements (%d) matching '%s' found." % (count, xpath)
576 
577 
593  def get_elements(self, source, xpath):
594  if isinstance(source, (str, bytes, os.PathLike)):
595  source = self.parse_xmlparse_xml(source)
596  finder = ElementFinder(self.etreeetree, self.modern_etreemodern_etree, self.lxml_etreelxml_etree)
597  return finder.find_all(source, xpath)
598 
599 
614  def get_child_elements(self, source, xpath='.'):
615  return list(self.get_elementget_element(source, xpath))
616 
617 
624  def get_element_count(self, source, xpath='.'):
625  count = len(self.get_elementsget_elements(source, xpath))
626  logger.info("%d element%s matched '%s'." % (count, s(count), xpath))
627  return count
628 
629 
639  def element_should_exist(self, source, xpath='.', message=None):
640  count = self.get_element_countget_element_count(source, xpath)
641  if not count:
642  self._raise_wrong_number_of_matches_raise_wrong_number_of_matches(count, xpath, message)
643 
644 
654  def element_should_not_exist(self, source, xpath='.', message=None):
655  count = self.get_element_countget_element_count(source, xpath)
656  if count:
657  self._raise_wrong_number_of_matches_raise_wrong_number_of_matches(count, xpath, message)
658 
659 
689  def get_element_text(self, source, xpath='.', normalize_whitespace=False):
690  element = self.get_elementget_element(source, xpath)
691  text = ''.join(self._yield_texts_yield_texts(element))
692  if is_truthy(normalize_whitespace):
693  text = self._normalize_whitespace_normalize_whitespace(text)
694  return text
695 
696  def _yield_texts(self, element, top=True):
697  if element.text:
698  yield element.text
699  for child in element:
700  for text in self._yield_texts_yield_texts(child, top=False):
701  yield text
702  if element.tail and not top:
703  yield element.tail
704 
705  def _normalize_whitespace(self, text):
706  return ' '.join(text.split())
707 
708 
724  def get_elements_texts(self, source, xpath, normalize_whitespace=False):
725  return [self.get_element_textget_element_text(elem, normalize_whitespace=normalize_whitespace)
726  for elem in self.get_elementsget_elements(source, xpath)]
727 
728 
750  def element_text_should_be(self, source, expected, xpath='.',
751  normalize_whitespace=False, message=None):
752  text = self.get_element_textget_element_text(source, xpath, normalize_whitespace)
753  should_be_equal(text, expected, message, values=False)
754 
755 
770  def element_text_should_match(self, source, pattern, xpath='.',
771  normalize_whitespace=False, message=None):
772  text = self.get_element_textget_element_text(source, xpath, normalize_whitespace)
773  should_match(text, pattern, message, values=False)
774 
775  @keyword(types=None)
776 
795  def get_element_attribute(self, source, name, xpath='.', default=None):
796  return self.get_elementget_element(source, xpath).get(name, default)
797 
798 
815  def get_element_attributes(self, source, xpath='.'):
816  return dict(self.get_elementget_element(source, xpath).attrib)
817 
818 
838  def element_attribute_should_be(self, source, name, expected, xpath='.',
839  message=None):
840  attr = self.get_element_attributeget_element_attribute(source, name, xpath)
841  should_be_equal(attr, expected, message, values=False)
842 
843 
857  def element_attribute_should_match(self, source, name, pattern, xpath='.',
858  message=None):
859  attr = self.get_element_attributeget_element_attribute(source, name, xpath)
860  if attr is None:
861  raise AssertionError("Attribute '%s' does not exist." % name)
862  should_match(attr, pattern, message, values=False)
863 
864 
880  def element_should_not_have_attribute(self, source, name, xpath='.', message=None):
881  attr = self.get_element_attributeget_element_attribute(source, name, xpath)
882  if attr is not None:
883  raise AssertionError(message or "Attribute '%s' exists and "
884  "has value '%s'." % (name, attr))
885 
886 
921  def elements_should_be_equal(self, source, expected, exclude_children=False,
922  normalize_whitespace=False):
923  self._compare_elements_compare_elements(source, expected, should_be_equal,
924  exclude_children, normalize_whitespace)
925 
926 
942  def elements_should_match(self, source, expected, exclude_children=False,
943  normalize_whitespace=False):
944  self._compare_elements_compare_elements(source, expected, should_match,
945  exclude_children, normalize_whitespace)
946 
947  def _compare_elements(self, source, expected, comparator, exclude_children,
948  normalize_whitespace):
949  normalizer = self._normalize_whitespace_normalize_whitespace \
950  if is_truthy(normalize_whitespace) else None
951  comparator = ElementComparator(comparator, normalizer, exclude_children)
952  comparator.compare(self.get_elementget_element(source), self.get_elementget_element(expected))
953 
954 
971  def set_element_tag(self, source, tag, xpath='.'):
972  source = self.get_elementget_element(source)
973  self.get_elementget_element(source, xpath).tag = tag
974  return source
975 
976 
981  def set_elements_tag(self, source, tag, xpath='.'):
982  source = self.get_elementget_element(source)
983  for elem in self.get_elementsget_elements(source, xpath):
984  self.set_element_tagset_element_tag(elem, tag)
985  return source
986 
987  @keyword(types=None)
988 
1010  def set_element_text(self, source, text=None, tail=None, xpath='.'):
1011  source = self.get_elementget_element(source)
1012  element = self.get_elementget_element(source, xpath)
1013  if text is not None:
1014  element.text = text
1015  if tail is not None:
1016  element.tail = tail
1017  return source
1018 
1019  @keyword(types=None)
1020 
1025  def set_elements_text(self, source, text=None, tail=None, xpath='.'):
1026  source = self.get_elementget_element(source)
1027  for elem in self.get_elementsget_elements(source, xpath):
1028  self.set_element_textset_element_text(elem, text, tail)
1029  return source
1030 
1031 
1051  def set_element_attribute(self, source, name, value, xpath='.'):
1052  if not name:
1053  raise RuntimeError('Attribute name can not be empty.')
1054  source = self.get_elementget_element(source)
1055  self.get_elementget_element(source, xpath).attrib[name] = value
1056  return source
1057 
1058 
1063  def set_elements_attribute(self, source, name, value, xpath='.'):
1064  source = self.get_elementget_element(source)
1065  for elem in self.get_elementsget_elements(source, xpath):
1066  self.set_element_attributeset_element_attribute(elem, name, value)
1067  return source
1068 
1069 
1087  def remove_element_attribute(self, source, name, xpath='.'):
1088  source = self.get_elementget_element(source)
1089  attrib = self.get_elementget_element(source, xpath).attrib
1090  if name in attrib:
1091  attrib.pop(name)
1092  return source
1093 
1094 
1099  def remove_elements_attribute(self, source, name, xpath='.'):
1100  source = self.get_elementget_element(source)
1101  for elem in self.get_elementsget_elements(source, xpath):
1102  self.remove_element_attributeremove_element_attribute(elem, name)
1103  return source
1104 
1105 
1122  def remove_element_attributes(self, source, xpath='.'):
1123  source = self.get_elementget_element(source)
1124  self.get_elementget_element(source, xpath).attrib.clear()
1125  return source
1126 
1127 
1132  def remove_elements_attributes(self, source, xpath='.'):
1133  source = self.get_elementget_element(source)
1134  for elem in self.get_elementsget_elements(source, xpath):
1135  self.remove_element_attributesremove_element_attributes(elem)
1136  return source
1137 
1138 
1164  def add_element(self, source, element, index=None, xpath='.'):
1165  source = self.get_elementget_element(source)
1166  parent = self.get_elementget_element(source, xpath)
1167  element = self.copy_elementcopy_element(element)
1168  if index is None:
1169  parent.append(element)
1170  else:
1171  parent.insert(int(index), element)
1172  return source
1173 
1174 
1195  def remove_element(self, source, xpath='', remove_tail=False):
1196  source = self.get_elementget_element(source)
1197  self._remove_element_remove_element(source, self.get_elementget_element(source, xpath), remove_tail)
1198  return source
1199 
1200 
1218  def remove_elements(self, source, xpath='', remove_tail=False):
1219  source = self.get_elementget_element(source)
1220  for element in self.get_elementsget_elements(source, xpath):
1221  self._remove_element_remove_element(source, element, remove_tail)
1222  return source
1223 
1224  def _remove_element(self, root, element, remove_tail=False):
1225  parent = self._find_parent_find_parent(root, element)
1226  if not is_truthy(remove_tail):
1227  self._preserve_tail_preserve_tail(element, parent)
1228  parent.remove(element)
1229 
1230  def _find_parent(self, root, element):
1231  for parent in root.iter():
1232  for child in parent:
1233  if child is element:
1234  return parent
1235  raise RuntimeError('Cannot remove root element.')
1236 
1237  def _preserve_tail(self, element, parent):
1238  if not element.tail:
1239  return
1240  index = list(parent).index(element)
1241  if index == 0:
1242  parent.text = (parent.text or '') + element.tail
1243  else:
1244  sibling = parent[index-1]
1245  sibling.tail = (sibling.tail or '') + element.tail
1246 
1247 
1271  def clear_element(self, source, xpath='.', clear_tail=False):
1272  source = self.get_elementget_element(source)
1273  element = self.get_elementget_element(source, xpath)
1274  tail = element.tail
1275  element.clear()
1276  if not is_truthy(clear_tail):
1277  element.tail = tail
1278  return source
1279 
1280 
1298  def copy_element(self, source, xpath='.'):
1299  return copy.deepcopy(self.get_elementget_element(source, xpath))
1300 
1301 
1313  def element_to_string(self, source, xpath='.', encoding=None):
1314  source = self.get_elementget_element(source, xpath)
1315  string = self.etreeetree.tostring(source, encoding='UTF-8').decode('UTF-8')
1316  string = self._xml_declaration_xml_declaration.sub('', string).strip()
1317  if encoding:
1318  string = string.encode(encoding)
1319  return string
1320 
1321 
1329  def log_element(self, source, level='INFO', xpath='.'):
1330  string = self.element_to_stringelement_to_string(source, xpath)
1331  logger.write(string, level)
1332  return string
1333 
1334 
1353  def save_xml(self, source, path, encoding='UTF-8'):
1354  path = os.path.abspath(str(path) if isinstance(path, os.PathLike)
1355  else path.replace('/', os.sep))
1356  elem = self.get_elementget_element(source)
1357  tree = self.etreeetree.ElementTree(elem)
1358  config = {'encoding': encoding}
1359  if self.modern_etreemodern_etree:
1360  config['xml_declaration'] = True
1361  if self.lxml_etreelxml_etree:
1362  elem = self._ns_stripper_ns_stripper.unstrip(elem)
1363  # https://bugs.launchpad.net/lxml/+bug/1660433
1364  if tree.docinfo.doctype:
1365  config['doctype'] = tree.docinfo.doctype
1366  tree = self.etreeetree.ElementTree(elem)
1367  with open(path, 'wb') as output:
1368  if 'doctype' in config:
1369  output.write(self.etreeetree.tostring(tree, **config))
1370  else:
1371  tree.write(output, **config)
1372  logger.info('XML saved to <a href="file://%s">%s</a>.' % (path, path),
1373  html=True)
1374 
1375 
1396  def evaluate_xpath(self, source, expression, context='.'):
1397  if not self.lxml_etreelxml_etree:
1398  raise RuntimeError("'Evaluate Xpath' keyword only works in lxml mode.")
1399  return self.get_elementget_element(source, context).xpath(expression)
1400 
1401 
1403 
1404  def __init__(self, etree, lxml_etree=False):
1405  self.etreeetree = etree
1406  self.lxml_treelxml_tree = lxml_etree
1407 
1408  def strip(self, elem, preserve=True, current_ns=None, top=True):
1409  if elem.tag.startswith('{') and '}' in elem.tag:
1410  ns, elem.tag = elem.tag[1:].split('}', 1)
1411  if preserve and ns != current_ns:
1412  elem.attrib['xmlns'] = ns
1413  current_ns = ns
1414  elif current_ns:
1415  elem.attrib['xmlns'] = ''
1416  current_ns = None
1417  for child in elem:
1418  self.stripstrip(child, preserve, current_ns, top=False)
1419  if top and not preserve and self.lxml_treelxml_tree:
1420  self.etreeetree.cleanup_namespaces(elem)
1421 
1422  def unstrip(self, elem, current_ns=None, copied=False):
1423  if not copied:
1424  elem = copy.deepcopy(elem)
1425  ns = elem.attrib.pop('xmlns', current_ns)
1426  if ns:
1427  elem.tag = '{%s}%s' % (ns, elem.tag)
1428  for child in elem:
1429  self.unstripunstrip(child, ns, copied=True)
1430  return elem
1431 
1432 
1434 
1435  def __init__(self, etree, modern=True, lxml=False):
1436  self.etreeetree = etree
1437  self.modernmodern = modern
1438  self.lxmllxml = lxml
1439 
1440  def find_all(self, elem, xpath):
1441  xpath = self._get_xpath_get_xpath(xpath)
1442  if xpath == '.': # ET < 1.3 does not support '.' alone.
1443  return [elem]
1444  if not self.lxmllxml:
1445  return elem.findall(xpath)
1446  finder = self.etreeetree.ETXPath(xpath)
1447  return finder(elem)
1448 
1449  def _get_xpath(self, xpath):
1450  if not xpath:
1451  raise RuntimeError('No xpath given.')
1452  if self.modernmodern:
1453  return xpath
1454  try:
1455  return str(xpath)
1456  except UnicodeError:
1457  if not xpath.replace('/', '').isalnum():
1458  logger.warn('XPATHs containing non-ASCII characters and '
1459  'other than tag names do not always work with '
1460  'Python versions prior to 2.7. Verify results '
1461  'manually and consider upgrading to 2.7.')
1462  return xpath
1463 
1464 
1466 
1467  def __init__(self, comparator, normalizer=None, exclude_children=False):
1468  self._comparator_comparator = comparator
1469  self._normalizer_normalizer = normalizer or (lambda text: text)
1470  self._exclude_children_exclude_children = is_truthy(exclude_children)
1471 
1472  def compare(self, actual, expected, location=None):
1473  if not location:
1474  location = Location(actual.tag)
1475  self._compare_tags_compare_tags(actual, expected, location)
1476  self._compare_attributes_compare_attributes(actual, expected, location)
1477  self._compare_texts_compare_texts(actual, expected, location)
1478  if location.is_not_root:
1479  self._compare_tails_compare_tails(actual, expected, location)
1480  if not self._exclude_children_exclude_children:
1481  self._compare_children_compare_children(actual, expected, location)
1482 
1483  def _compare_tags(self, actual, expected, location):
1484  self._compare_compare(actual.tag, expected.tag, 'Different tag name', location,
1485  should_be_equal)
1486 
1487  def _compare(self, actual, expected, message, location, comparator=None):
1488  if location.is_not_root:
1489  message = "%s at '%s'" % (message, location.path)
1490  if not comparator:
1491  comparator = self._comparator_comparator
1492  comparator(actual, expected, message)
1493 
1494  def _compare_attributes(self, actual, expected, location):
1495  self._compare_compare(sorted(actual.attrib), sorted(expected.attrib),
1496  'Different attribute names', location, should_be_equal)
1497  for key in actual.attrib:
1498  self._compare_compare(actual.attrib[key], expected.attrib[key],
1499  "Different value for attribute '%s'" % key, location)
1500 
1501  def _compare_texts(self, actual, expected, location):
1502  self._compare_compare(self._text_text(actual.text), self._text_text(expected.text),
1503  'Different text', location)
1504 
1505  def _text(self, text):
1506  return self._normalizer_normalizer(text or '')
1507 
1508  def _compare_tails(self, actual, expected, location):
1509  self._compare_compare(self._text_text(actual.tail), self._text_text(expected.tail),
1510  'Different tail text', location)
1511 
1512  def _compare_children(self, actual, expected, location):
1513  self._compare_compare(len(actual), len(expected), 'Different number of child elements',
1514  location, should_be_equal)
1515  for act, exp in zip(actual, expected):
1516  self.comparecompare(act, exp, location.child(act.tag))
1517 
1518 
1519 class Location:
1520 
1521  def __init__(self, path, is_root=True):
1522  self.pathpath = path
1523  self.is_not_rootis_not_root = not is_root
1524  self._children_children = {}
1525 
1526  def child(self, tag):
1527  if tag not in self._children_children:
1528  self._children_children[tag] = 1
1529  else:
1530  self._children_children[tag] += 1
1531  tag += '[%d]' % self._children_children[tag]
1532  return Location('%s/%s' % (self.pathpath, tag), is_root=False)
An always available standard library with often needed keywords.
Definition: BuiltIn.py:3944
def _compare(self, actual, expected, message, location, comparator=None)
Definition: XML.py:1487
def _compare_attributes(self, actual, expected, location)
Definition: XML.py:1494
def _compare_texts(self, actual, expected, location)
Definition: XML.py:1501
def _compare_children(self, actual, expected, location)
Definition: XML.py:1512
def compare(self, actual, expected, location=None)
Definition: XML.py:1472
def _compare_tails(self, actual, expected, location)
Definition: XML.py:1508
def _compare_tags(self, actual, expected, location)
Definition: XML.py:1483
def __init__(self, comparator, normalizer=None, exclude_children=False)
Definition: XML.py:1467
def _get_xpath(self, xpath)
Definition: XML.py:1449
def find_all(self, elem, xpath)
Definition: XML.py:1440
def __init__(self, etree, modern=True, lxml=False)
Definition: XML.py:1435
def __init__(self, path, is_root=True)
Definition: XML.py:1521
def child(self, tag)
Definition: XML.py:1526
def unstrip(self, elem, current_ns=None, copied=False)
Definition: XML.py:1422
def __init__(self, etree, lxml_etree=False)
Definition: XML.py:1404
def strip(self, elem, preserve=True, current_ns=None, top=True)
Definition: XML.py:1408
Robot Framework library for verifying and modifying XML documents.
Definition: XML.py:456
def get_element_attributes(self, source, xpath='.')
Returns all attributes of the specified element.
Definition: XML.py:815
def _find_parent(self, root, element)
Definition: XML.py:1230
def get_elements(self, source, xpath)
Returns a list of elements in the source matching the xpath.
Definition: XML.py:593
def element_attribute_should_match(self, source, name, pattern, xpath='.', message=None)
Verifies that the specified attribute matches expected.
Definition: XML.py:858
def __init__(self, use_lxml=False)
Import library with optionally lxml mode enabled.
Definition: XML.py:476
def get_element_count(self, source, xpath='.')
Returns and logs how many elements the given xpath matches.
Definition: XML.py:624
def get_element(self, source, xpath='.')
Returns an element in the source matching the xpath.
Definition: XML.py:559
def _wrong_number_of_matches(self, count, xpath)
Definition: XML.py:570
def _normalize_whitespace(self, text)
Definition: XML.py:705
def element_should_not_have_attribute(self, source, name, xpath='.', message=None)
Verifies that the specified element does not have attribute name.
Definition: XML.py:880
def get_element_attribute(self, source, name, xpath='.', default=None)
Returns the named attribute of the specified element.
Definition: XML.py:795
def remove_elements_attributes(self, source, xpath='.')
Removes all attributes from the specified elements.
Definition: XML.py:1132
def element_attribute_should_be(self, source, name, expected, xpath='.', message=None)
Verifies that the specified attribute is expected.
Definition: XML.py:839
def remove_element_attribute(self, source, name, xpath='.')
Removes attribute name from the specified element.
Definition: XML.py:1087
def set_element_text(self, source, text=None, tail=None, xpath='.')
Sets text and/or tail text of the specified element.
Definition: XML.py:1010
def remove_element(self, source, xpath='', remove_tail=False)
Removes the element matching xpath from the source structure.
Definition: XML.py:1195
def set_elements_tag(self, source, tag, xpath='.')
Sets the tag of the specified elements.
Definition: XML.py:981
def set_elements_attribute(self, source, name, value, xpath='.')
Sets attribute name of the specified elements to value.
Definition: XML.py:1063
def add_element(self, source, element, index=None, xpath='.')
Adds a child element to the specified element.
Definition: XML.py:1164
def get_elements_texts(self, source, xpath, normalize_whitespace=False)
Returns text of all elements matching xpath as a list.
Definition: XML.py:724
def _yield_texts(self, element, top=True)
Definition: XML.py:696
def _preserve_tail(self, element, parent)
Definition: XML.py:1237
def element_should_not_exist(self, source, xpath='.', message=None)
Verifies that no element match the given xpath.
Definition: XML.py:654
def element_should_exist(self, source, xpath='.', message=None)
Verifies that one or more element match the given xpath.
Definition: XML.py:639
def set_element_attribute(self, source, name, value, xpath='.')
Sets attribute name of the specified element to value.
Definition: XML.py:1051
def element_text_should_be(self, source, expected, xpath='.', normalize_whitespace=False, message=None)
Verifies that the text of the specified element is expected.
Definition: XML.py:751
def parse_xml(self, source, keep_clark_notation=False, strip_namespaces=False)
Parses the given XML file or string into an element structure.
Definition: XML.py:521
def set_element_tag(self, source, tag, xpath='.')
Sets the tag of the specified element.
Definition: XML.py:971
def _raise_wrong_number_of_matches(self, count, xpath, message=None)
Definition: XML.py:565
def copy_element(self, source, xpath='.')
Returns a copy of the specified element.
Definition: XML.py:1298
def save_xml(self, source, path, encoding='UTF-8')
Saves the given element to the specified file.
Definition: XML.py:1353
def elements_should_match(self, source, expected, exclude_children=False, normalize_whitespace=False)
Verifies that the given source element matches expected.
Definition: XML.py:943
def remove_elements(self, source, xpath='', remove_tail=False)
Removes all elements matching xpath from the source structure.
Definition: XML.py:1218
def log_element(self, source, level='INFO', xpath='.')
Logs the string representation of the specified element.
Definition: XML.py:1329
def _remove_element(self, root, element, remove_tail=False)
Definition: XML.py:1224
def clear_element(self, source, xpath='.', clear_tail=False)
Clears the contents of the specified element.
Definition: XML.py:1271
def remove_element_attributes(self, source, xpath='.')
Removes all attributes from the specified element.
Definition: XML.py:1122
def _compare_elements(self, source, expected, comparator, exclude_children, normalize_whitespace)
Definition: XML.py:948
def element_to_string(self, source, xpath='.', encoding=None)
Returns the string representation of the specified element.
Definition: XML.py:1313
def get_element_text(self, source, xpath='.', normalize_whitespace=False)
Returns all text of the element, possibly whitespace normalized.
Definition: XML.py:689
def set_elements_text(self, source, text=None, tail=None, xpath='.')
Sets text and/or tail text of the specified elements.
Definition: XML.py:1025
def element_text_should_match(self, source, pattern, xpath='.', normalize_whitespace=False, message=None)
Verifies that the text of the specified element matches expected.
Definition: XML.py:771
def remove_elements_attribute(self, source, name, xpath='.')
Removes attribute name from the specified elements.
Definition: XML.py:1099
def get_child_elements(self, source, xpath='.')
Returns the child elements of the specified element as a list.
Definition: XML.py:614
def evaluate_xpath(self, source, expression, context='.')
Evaluates the given xpath expression and returns results.
Definition: XML.py:1396
def elements_should_be_equal(self, source, expected, exclude_children=False, normalize_whitespace=False)
Verifies that the given source element is equal to expected.
Definition: XML.py:922
def is_truthy(item)
Returns True or False depending on is the item considered true or not.
Definition: robottypes.py:162
def is_falsy(item)
Opposite of :func:is_truthy.
Definition: robottypes.py:169
def get_version(naked=False)
Definition: version.py:24