Пример #1
0
def _validate_xml(spec, data, xmltext):
    """Validate the decoded xml.

    We don't just use the internal xml and compare it against the external xm;
    there may be differences in whitespace, and some fields can be represented
    in multiple ways (eg: 5.0 vs 5.00000 vs 5).
    """
    xml_entries = xml.etree.ElementTree.iterparse(StringIO.StringIO(xmltext), ['start', 'end'])
    child_tail=None
    for (is_starting, name, entry, data, expected), (a_event, a_elem) in itertools.izip(_decode_visible(spec, data), xml_entries):
        if is_starting and a_event != 'start':
            raise Exception ("Expected '%s' to be starting, but got '%s' ending" %
                    (name, a_elem.tag))
        if not is_starting and a_event != 'end':
            raise Exception ("Expected '%s' to be ending, but got '%s' starting" %
                    (name, a_elem.tag))
        if xmlout.escape_name(name) != a_elem.tag:
            raise Exception("expected '%s', got '%s'" %
                    (xmlout.escape_name(name), a_elem.tag))
        if not is_starting:
            text = a_elem.text
            if not text or not  text.strip() and child_tail is not None:
                # We don't have a text node for this child; try using its
                # child's trailing text.
                text = child_tail
            if not text or not text.strip():
                # This node doesn't have data; it's possible that it has an
                # expected value, so wasn't printed. Get the expected value
                # from the constraint.
                try:
                    text = _get_expected(entry)
                except _NoExpectedError:
                    # We don't have an expected value; stick with the existing
                    # text.
                    pass
                except _ComplexExpectedError:
                    # We have an expected value that is difficult to evaluate.
                    # Just use the existing expected... this effectively short
                    # circuits the test.
                    text = expected
            if text is None:
                text = ''

            if expected is not None:
                if isinstance(entry, fld.Field):
                    actual = convert_value(entry, text, len(data))
                else:
                    actual = int(text)
                if expected != actual:
                    # If the value is different, it may be that the data cannot
                    # be represented in xml (eg: a string with a binary
                    # character). Encode and decode the expected value to see if
                    # matches now (being escaped itself...)
                    expected_text = xmlout.xml_strip(unicode(expected))
                    escaped_expected = convert_value(entry, expected_text, len(data))
                    constraint = Equals(escaped_expected)
                    constraint.check(entry, actual, {})
            elif a_elem.text is not None and a_elem.text.strip():
                raise Exception("Expected empty text in entry '%s', got '%s'!" %
                        (a_elem.tag, a_elem.text))
            child_tail=a_elem.tail
        else:
            child_tail=None