def test_get_namespace(self): self.assertEqual(get_namespace(''), '') self.assertEqual(get_namespace('local'), '') self.assertEqual(get_namespace(XSD_ELEMENT), XSD_NAMESPACE) self.assertEqual(get_namespace('{wrong'), '') self.assertEqual(get_namespace(''), '') self.assertEqual(get_namespace(None), '') self.assertEqual(get_namespace('{}name'), '') self.assertEqual(get_namespace('{ }name'), ' ') self.assertEqual(get_namespace('{ ns }name'), ' ns ')
def retrieve_schema_source(self, source): """ Returns a schema source that can be used to create an XMLSchema instance. :param source: A string or an ElementTree's Element. :return: An schema source string, an ElementTree's Element or a full pathname. """ if is_etree_element(source): if source.tag in (XSD_SCHEMA, 'schema'): return source elif get_namespace(source.tag): raise XMLSchemaValueError("source %r namespace has to be empty." % source) elif source.tag not in {'element', 'attribute', 'simpleType', 'complexType', 'group', 'attributeGroup', 'notation'}: raise XMLSchemaValueError("% is not an XSD global definition/declaration." % source) root = etree_element('schema', attrib={ 'xmlns:ns': "ns", 'xmlns': "http://www.w3.org/2001/XMLSchema", 'targetNamespace': "ns", 'elementFormDefault': "qualified", 'version': self.schema_class.XSD_VERSION, }) root.append(source) return root else: source = source.strip() if not source.startswith('<'): return self.casepath(source) else: return self.SCHEMA_TEMPLATE.format(self.schema_class.XSD_VERSION, source)
def test_get_namespace_function(self): self.assertEqual(get_namespace(XSD_SIMPLE_TYPE), XSD_NAMESPACE) self.assertEqual(get_namespace(''), '') self.assertEqual(get_namespace(None), '')
def etree_elements_assert_equal(elem, other, strict=True, skip_comments=True, unordered=False): """ Tests the equality of two XML Element trees. :param elem: the master Element tree, reference for namespace mapping. :param other: the other Element tree that has to be compared. :param strict: asserts strictly equality. `True` for default. :param skip_comments: skip comments from comparison. :param unordered: children may have different order. :raise: an AssertionError containing information about first difference encountered. """ if unordered: children = sorted(elem, key=lambda x: '' if callable(x.tag) else x.tag) other_children = iter( sorted(other, key=lambda x: '' if callable(x.tag) else x.tag)) else: children = elem other_children = iter(other) namespace = '' for e1 in children: if skip_comments and callable(e1.tag): continue try: while True: e2 = next(other_children) if not skip_comments or not callable(e2.tag): break except StopIteration: raise AssertionError("Node %r has more children than %r" % (elem, other)) if strict or e1 is elem: if e1.tag != e2.tag: raise AssertionError("%r != %r: tags differ" % (e1, e2)) else: namespace = get_namespace(e1.tag) or namespace if get_qname(namespace, e1.tag) != get_qname(namespace, e2.tag): raise AssertionError("%r != %r: tags differ." % (e1, e2)) # Attributes if e1.attrib != e2.attrib: if strict: msg = "{!r} != {!r}: attributes differ: {!r} != {!r}" raise AssertionError(msg.format(e1, e2, e1.attrib, e2.attrib)) else: msg = "%r != %r: attribute keys differ: %r != %r" if sorted(e1.attrib.keys()) != sorted(e2.attrib.keys()): raise AssertionError( msg % (e1, e2, e1.attrib.keys(), e2.attrib.keys())) for k in e1.attrib: a1, a2 = e1.attrib[k].strip(), e2.attrib[k].strip() if a1 != a2: try: if float(a1) != float(a2): raise ValueError() except (ValueError, TypeError): msg = "%r != %r: attribute %r values differ: %r != %r" raise AssertionError(msg % (e1, e2, k, a1, a2)) from None # Number of children if skip_comments: nc1 = len([c for c in e1 if not callable(c.tag)]) nc2 = len([c for c in e2 if not callable(c.tag)]) else: nc1 = len(e1) nc2 = len(e2) if nc1 != nc2: msg = "%r != %r: children number differ: %r != %r" raise AssertionError(msg % (e1, e2, nc1, nc2)) # Text if e1.text != e2.text: message = "%r != %r: texts differ: %r != %r" % (e1, e2, e1.text, e2.text) if strict: raise AssertionError(message) elif e1.text is None: if e2.text.strip(): raise AssertionError(message) elif e2.text is None: if e1.text.strip(): raise AssertionError(message) elif _REGEX_SPACES.sub('', e1.text.strip()) != _REGEX_SPACES.sub( '', e2.text.strip()): text1 = e1.text.strip() text2 = e2.text.strip() if text1 == 'false': if text2 != '0': raise AssertionError(message) elif text1 == 'true': if text2 != '1': raise AssertionError(message) elif text2 == 'false': if text1 != '0': raise AssertionError(message) elif text2 == 'true': if text1 != '1': raise AssertionError(message) else: try: items1 = text1.split() items2 = text2.split() if len(items1) != len(items2): raise ValueError() if not all( float(x1) == float(x2) for x1, x2 in zip(items1, items2)): raise ValueError() except (AssertionError, ValueError, TypeError): raise AssertionError(message) from None # Tail if e1.tail != e2.tail: message = "%r != %r: tails differ: %r != %r" % (e1, e2, e1.tail, e2.tail) if strict: raise AssertionError(message) elif e1.tail is None: if e2.tail.strip(): raise AssertionError(message) elif e2.tail is None: if e1.tail.strip(): raise AssertionError(message) elif e1.tail.strip() != e2.tail.strip(): raise AssertionError(message) etree_elements_assert_equal(e1, e2, strict, skip_comments, unordered) try: next(other_children) except StopIteration: pass else: raise AssertionError("Node %r has lesser children than %r." % (elem, other))
def etree_elements_assert_equal(elem, other, strict=True, skip_comments=True): """ Tests the equality of two XML Element trees. :param elem: the master Element tree, reference for namespace mapping. :param other: the other Element tree that has to be compared. :param strict: asserts strictly equality. `True` for default. :param skip_comments: Skip comments for e :raise: an AssertionError containing information about first difference encountered. """ _REGEX_SPACES = re.compile(r'\s+') other_elements = iter(other.iter()) namespace = '' for e1 in elem.iter(): if skip_comments and e1.tag is lxml_etree_comment: continue try: e2 = next(other_elements) except StopIteration: assert False, "Second tree ends before the first: %r." % e1 if strict or e1 is elem: assert e1.tag == e2.tag, "%r != %r: tags differ." % (e1, e2) else: namespace = get_namespace(e1.tag) or namespace assert get_qname(namespace, e1.tag) == get_qname( namespace, e1.tag), "%r != %r: tags differ." % (e1, e2) # Attributes if e1.attrib != e2.attrib: if strict: raise AssertionError("%r != %r: attribute differ: %r != %r." % (e1, e2, e1.attrib, e2.attrib)) else: assert e1.attrib.keys() == e2.attrib.keys(), \ "%r != %r: attribute keys differ: %r != %r." % (e1, e2, e1.attrib.keys(), e2.attrib.keys()) for k in e1.attrib: a1, a2 = e1.attrib[k].strip(), e2.attrib[k].strip() if a1 != a2: try: assert float(a1) == float(a2) except (AssertionError, ValueError, TypeError): raise AssertionError( "%r != %r: attribute %r differ: %r != %r." % (e1, e2, k, a1, a2)) # Number of children if skip_comments: nc1 = len([c for c in e1 if c.tag is not lxml_etree_comment]) nc2 = len([c for c in e2 if c.tag is not lxml_etree_comment]) else: nc1 = len(e1) nc2 = len(e2) assert nc1 == nc2, "%r != %r: children number differ: %r != %r." % ( e1, e2, nc1, nc2) # Text if e1.text != e2.text: message = "%r != %r: texts differ: %r != %r." % (e1, e2, e1.text, e2.text) if strict: raise AssertionError(message) elif e1.text is None: assert not e2.text.strip(), message elif e2.text is None: assert not e1.text.strip(), message elif _REGEX_SPACES.sub(e1.text.strip(), '') != _REGEX_SPACES.sub( e2.text.strip(), ''): try: assert float(e1.text.strip()) == float(e2.text.strip()) except (AssertionError, ValueError, TypeError): raise AssertionError(message) # Tail if e1.tail != e2.tail: message = "%r != %r: tails differ: %r != %r." % (e1, e2, e1.tail, e2.tail) if strict: raise AssertionError(message) elif e1.tail is None: assert not e2.tail.strip(), message elif e2.text is None: assert not e1.tail.strip(), message else: assert e1.tail.strip() == e2.tail.strip(), message try: e2 = next(other_elements) except StopIteration: pass else: assert False, "First tree ends before the second: %r." % e2