Exemplo n.º 1
0
    def validate(self, doc, version=None):
        """Checks that a STIX document aligns with `suggested authoring
        practices`_.

        .. _suggested authoring practices: http://stixproject.github.io/documentation/suggested-practices/

        Args:
            doc: The STIX document. Can be a filename, file-like object,
                lxml._Element, or lxml._ElementTree instance.
            version: The version of the STIX document. This will determine the
                set of best practice rules to check. If ``None`` an attempt
                will be made to extract the version from `doc`.

        Returns:
            An instance of
            :class:`.BestPracticeValidationResults`.

        Raises:
            .UnknownSTIXVersionError: If `version` was ``None`` and `doc`
                did not contain any version information.
            .InvalidSTIXVersionError: If discovered version or `version`
                argument contains an invalid STIX version number.
            .ValidationError: If there are any issues parsing `doc`.

        """
        root = utils.get_etree_root(doc)
        version = version or self._get_version(doc)

        stix.check_version(version)
        results = self._run_rules(root, version)

        return results
Exemplo n.º 2
0
 def test_get_etree_root_element(self):
     sio = StringIO(XML)
     tree = etree.parse(sio)
     newroot = tree.getroot()
     root = utils.get_etree_root(newroot)
     lname = etree.QName(root).localname
     self.assertEqual(lname, XML_ROOT_LOCALNAME)
    def _build_required_imports(self, doc, schemaloc=False):
        root = utils.get_etree_root(doc)

        if schemaloc:
            return self._parse_schemaloc(root)

        return self._get_required_schemas(root)
Exemplo n.º 4
0
def get_version(doc):
    """Returns the version of the `observables` ``Observables`` node.

    Returns:
        A dotted-decimal a version string from the ``cybox_major``,
        ``cybox_minor`` and ``cybox_update`` attribute values.

    Raises:
        UnknownVersionError: If `observables` does not contain any of the
            following attributes:

            * ``cybox_major_version``
            * ``cybox_minor_version``
            * ``cybox_update_version``

    """
    observables  = utils.get_etree_root(doc)
    cybox_major  = observables.attrib.get(TAG_CYBOX_MAJOR)
    cybox_minor  = observables.attrib.get(TAG_CYBOX_MINOR)
    cybox_update = observables.attrib.get(TAG_CYBOX_UPDATE)

    if not any((cybox_major, cybox_minor, cybox_update)):
        error = "The input CybOX document has no version information."
        raise errors.UnknownCyboxVersionError(error)

    if cybox_update not in (None, '0'):
        version = "%s.%s.%s" % (cybox_major, cybox_minor, cybox_update)
    else:
        version = "%s.%s" % (cybox_major, cybox_minor)

    return version
Exemplo n.º 5
0
def get_version(doc):
    """Returns the version of the `observables` ``Observables`` node.

    Returns:
        A dotted-decimal a version string from the ``cybox_major``,
        ``cybox_minor`` and ``cybox_update`` attribute values.

    Raises:
        UnknownVersionError: If `observables` does not contain any of the
            following attributes:

            * ``cybox_major_version``
            * ``cybox_minor_version``
            * ``cybox_update_version``

    """
    observables = utils.get_etree_root(doc)
    cybox_major = observables.attrib.get(TAG_CYBOX_MAJOR)
    cybox_minor = observables.attrib.get(TAG_CYBOX_MINOR)
    cybox_update = observables.attrib.get(TAG_CYBOX_UPDATE)

    if not any((cybox_major, cybox_minor, cybox_update)):
        error = "The input CybOX document has no version information."
        raise errors.UnknownCyboxVersionError(error)

    if cybox_update not in (None, '0'):
        version = "%s.%s.%s" % (cybox_major, cybox_minor, cybox_update)
    else:
        version = "%s.%s" % (cybox_major, cybox_minor)

    return version
Exemplo n.º 6
0
    def _build_schematron(self, sch, phase=None):
        """Attempts to build an ``lxml.isoschematron.Schematron`` instance
        from `sch`.

        Args:
            sch: A Schematron document filename, file-like object,
                etree._Element, or etree._ElementTree.

        Returns:
            A ``lxml.isoschematron.Schematron`` instance for `sch`.

        """
        if sch is None:
            raise ValueError("Input schematron document cannot be None")

        root = utils.get_etree_root(sch)
        schematron = lxml.isoschematron.Schematron(
            root,
            phase=phase,
            store_report=True,
            store_xslt=True,
            store_schematron=True
        )

        return schematron
Exemplo n.º 7
0
 def test_get_etree_root_element(self):
     sio = StringIO(XML)
     tree = etree.parse(sio)
     newroot = tree.getroot()
     root = utils.get_etree_root(newroot)
     lname = etree.QName(root).localname
     self.assertEqual(lname, XML_ROOT_LOCALNAME)
Exemplo n.º 8
0
    def _build_required_imports(self, doc, schemaloc=False):
        root = utils.get_etree_root(doc)

        if schemaloc:
            return self._parse_schemaloc(root)

        return self._get_required_schemas(root)
Exemplo n.º 9
0
def get_xml_validator_class(doc):
    """Returns the XML validator class required to validate the input
    `doc`.

    Args:
        doc: An XML document. This can be a filename, file-like object,
            ``etree._Element``, or ``etree._ElementTree`` instance.

    Returns:
        An XML Schema validator class (not object instance) which provides
        validation functionality required to validate `doc`.

    """
    root = utils.get_etree_root(doc)

    if utils.is_stix(root):
        return STIXSchemaValidator

    if utils.is_cybox(root):
        return CyboxSchemaValidator

    ns = utils.get_namespace(root)
    error = (
        "Unable determine validator class for input type. Root element "
        "namespace: {0}"
    ).format(ns)

    raise errors.ValidationError(error)
Exemplo n.º 10
0
def get_xml_validator_class(doc):
    """Returns the XML validator class required to validate the input
    `doc`.

    Args:
        doc: An XML document. This can be a filename, file-like object,
            ``etree._Element``, or ``etree._ElementTree`` instance.

    Returns:
        An XML Schema validator class (not object instance) which provides
        validation functionality required to validate `doc`.

    """
    root = utils.get_etree_root(doc)

    if utils.is_stix(root):
        return STIXSchemaValidator

    if utils.is_cybox(root):
        return CyboxSchemaValidator

    ns = utils.get_namespace(root)
    error = ("Unable determine validator class for input type. Root element "
             "namespace: {0}").format(ns)

    raise errors.ValidationError(error)
Exemplo n.º 11
0
 def test_get_schemaloc_pairs_raises(self):
     sio = StringIO(XML)
     root = utils.get_etree_root(sio)
     self.assertRaises(
         KeyError,
         utils.get_schemaloc_pairs,
         root
     )
Exemplo n.º 12
0
    def _get_line(self):
        """Returns the line number in the input document associated with this
        error.

        """
        root = utils.get_etree_root(self._doc)
        xpath = self._xpath_location
        nsmap = self._error.nsmap

        node = root.xpath(xpath, namespaces=nsmap)[0]
        return node.sourceline
Exemplo n.º 13
0
def idref_timestamp_resolves(root, idref, timestamp, namespaces):
    """Determines if an `idref` and `timestamp` pair resolve to an XML
    component under `root`.

    """
    root = utils.get_etree_root(root)
    timestamp = utils.parse_timestamp(timestamp)
    xpath = "//*[@id='{0}']".format(idref)
    nodes = root.xpath(xpath, namespaces=namespaces)

    return any(utils.is_equal_timestamp(timestamp, node) for node in nodes)
Exemplo n.º 14
0
    def _get_line(self):
        """Returns the line number in the input document associated with this
        error.

        """
        root = utils.get_etree_root(self._doc)
        xpath = self._xpath_location
        nsmap = self._error.nsmap

        node = root.xpath(xpath, namespaces=nsmap)[0]
        return node.sourceline
Exemplo n.º 15
0
def idref_timestamp_resolves(root, idref, timestamp, namespaces):
    """Determines if an `idref` and `timestamp` pair resolve to an XML
    component under `root`.

    """
    root = utils.get_etree_root(root)
    timestamp = utils.parse_timestamp(timestamp)
    xpath = "//*[@id='{0}']".format(idref)
    nodes = root.xpath(xpath, namespaces=namespaces)

    return any(utils.is_equal_timestamp(timestamp, node) for node in nodes)
Exemplo n.º 16
0
    def inner(*args, **kwargs):
        try:
            doc = args[1]
        except IndexError:
            doc = kwargs['doc']

        # Get the root element for the input doc
        root = utils.get_etree_root(doc)

        # Check that the root is a valid CybOX root-level element
        check_root(root)

        return func(*args, **kwargs)
Exemplo n.º 17
0
    def _check_stix(*args, **kwargs):
        try:
            doc = args[1]
        except IndexError:
            doc = kwargs['doc']

        # Get the root element for the input doc
        root = utils.get_etree_root(doc)

        # Check that the root is a valid STIX root-level element
        check_root(root)

        return func(*args, **kwargs)
Exemplo n.º 18
0
def get_version(doc):
    """Returns the version of a STIX instnace document.

    Args:
        doc: A STIX filename, file-like object, etree._Element or
            etree._ElementTree instance.

    Returns:
        The version of the document.

    Raises:
        KeyError: If the document does not contain a ``version`` attribute
            on the root node.
        .ValidationError: If there are any issues parsing `doc`.
    """
    root = utils.get_etree_root(doc)
    return root.attrib['version']
Exemplo n.º 19
0
    def _build_uber_schema(self, doc, schemaloc=False):
        """Builds a schema which is made up of ``xs:import`` directives for
        each schema required to validate `doc`.

        If schemaloc is ``True``, the ``xsi:schemaLocation`` attribute values
        are used to create the ``xs:import`` directives. If ``False``, the
        initialization schema directory is used.

        Returns:
            An ``etree.XMLSchema`` instance used to validate `doc`.

        Raise:
            .XMLSchemaImportError: If an error occurred while building the
                dictionary of namespace to schemalocation mappings used to
                drive the uber schema creation.

        """
        root = utils.get_etree_root(doc)
        imports = self._build_required_imports(root, schemaloc)

        if not imports:
            raise errors.XMLSchemaImportError(
                "Cannot validate document. Error occurred while determining "
                "schemas required for validation."
            )

        xsd = etree.fromstring(
            """
            <xs:schema
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                targetNamespace="http://stix.mitre.org/tools/validator"
                elementFormDefault="qualified"
                attributeFormDefault="qualified"/>
            """
        )

        for ns, loc in imports.iteritems():
            loc = loc.replace("\\", "/")
            attrib = {
                'namespace': ns,
                'schemaLocation': loc
            }
            import_ = etree.Element(TAG_XS_IMPORT, attrib=attrib)
            xsd.append(import_)

        return etree.XMLSchema(xsd)
Exemplo n.º 20
0
    def test_ts_tz_resolves(self):
        root = utils.get_etree_root(StringIO(TS_TZ_RESOLVES))

        offset_resolves = common.idref_timestamp_resolves(
            root=root,
            idref="example:campaign-1",
            timestamp="2015-04-14T15:24:19.416203+00:00",
            namespaces=common.get_stix_namespaces('1.1.1'))

        zulu_resolves = common.idref_timestamp_resolves(
            root=root,
            idref="example:campaign-1",
            timestamp="2015-04-14T15:24:19.416203Z",
            namespaces=common.get_stix_namespaces('1.1.1'))

        self.assertTrue(zulu_resolves)
        self.assertTrue(offset_resolves)
Exemplo n.º 21
0
    def validate(self, doc):
        """Validates an XML instance document against a STIX profile.

        Args:
            doc: The STIX document. This can be a filename, file-like object,
                ``etree._Element``, or ``etree._ElementTree`` instance.

        Returns:
            An instance of
            :class:`.ProfileValidationResults`.

        Raises:
            .ValidationError: If there are any issues parsing `doc`.
        """
        root = utils.get_etree_root(doc)
        is_valid = self._schematron.validate(root)
        svrl_report = self._schematron.validation_report
        results = ProfileValidationResults(is_valid, root, svrl_report)
        return results
    def test_ts_tz_resolves(self):
        root = utils.get_etree_root(StringIO(TS_TZ_RESOLVES))

        offset_resolves = common.idref_timestamp_resolves(
            root=root,
            idref="example:campaign-1",
            timestamp="2015-04-14T15:24:19.416203+00:00",
            namespaces=common.get_stix_namespaces('1.1.1')
        )

        zulu_resolves = common.idref_timestamp_resolves(
            root=root,
            idref="example:campaign-1",
            timestamp="2015-04-14T15:24:19.416203Z",
            namespaces=common.get_stix_namespaces('1.1.1')
        )

        self.assertTrue(zulu_resolves)
        self.assertTrue(offset_resolves)
Exemplo n.º 23
0
    def validate(self, doc):
        """Validates an XML instance document against a STIX profile.

        Args:
            doc: The STIX document. This can be a filename, file-like object,
                ``etree._Element``, or ``etree._ElementTree`` instance.

        Returns:
            An instance of
            :class:`.ProfileValidationResults`.

        Raises:
            .ValidationError: If there are any issues parsing `doc`.
        """
        root = utils.get_etree_root(doc)
        is_valid = self._schematron.validate(root)
        svrl_report = self._schematron.validation_report
        results = ProfileValidationResults(is_valid, root, svrl_report)
        return results
Exemplo n.º 24
0
    def _build_uber_schema(self, doc, schemaloc=False):
        """Builds a schema which is made up of ``xs:import`` directives for
        each schema required to validate `doc`.

        If schemaloc is ``True``, the ``xsi:schemaLocation`` attribute values
        are used to create the ``xs:import`` directives. If ``False``, the
        initialization schema directory is used.

        Returns:
            An ``etree.XMLSchema`` instance used to validate `doc`.

        Raise:
            .XMLSchemaImportError: If an error occurred while building the
                dictionary of namespace to schemalocation mappings used to
                drive the uber schema creation.

        """
        root = utils.get_etree_root(doc)
        imports = self._build_required_imports(root, schemaloc)

        if not imports:
            raise errors.XMLSchemaImportError(
                "Cannot validate document. Error occurred while determining "
                "schemas required for validation."
            )

        xsd = etree.fromstring(
            """
            <xs:schema
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                targetNamespace="http://stix.mitre.org/tools/validator"
                elementFormDefault="qualified"
                attributeFormDefault="qualified"/>
            """
        )

        for ns, loc in iteritems(imports):
            loc = loc.replace("\\", "/")
            attrib = {'namespace': ns, 'schemaLocation':loc}
            import_ = etree.Element(xmlconst.TAG_XS_IMPORT, attrib=attrib)
            xsd.append(import_)

        return etree.XMLSchema(xsd)
Exemplo n.º 25
0
    def validate(self, doc, version=None, schemaloc=False):
        """Performs XML Schema validation against a STIX document.

        Args:
            doc: The STIX document. This can be a filename, file-like object,
                ``etree._Element``, or ``etree._ElementTree`` instance.
            version: The version of the STIX document. If ``None`` an attempt
                will be made to extract the version from `doc`.
            schemaloc: If ``True``, the ``xsi:schemaLocation`` attribute on
                `doc` will be used to drive the validation.

        Returns:
            An instance of
            :class:`.XmlValidationResults`.

        Raises:
            .UnknownSTIXVersionError: If `version` is ``None`` and
                `doc` does not contain STIX version information.
            .InvalidSTIXVersionError: If `version` is an invalid
                STIX version or `doc` contains an invalid STIX version number.
            .ValidationError: If the class was not initialized with a
                schema directory and `schemaloc` is ``False``.
            .XMLSchemaImportError: If an error occurs while processing the
                schemas required for validation.
            .XMLSchemaIncludeError: If an error occurs while processing
                ``xs:include`` directives.
            .ValidationError: If there are any issues parsing `doc`.

        """
        root = utils.get_etree_root(doc)

        if schemaloc:
            validator = self._xml_validators[self._KEY_SCHEMALOC]
        elif self._is_user_defined:
            validator = self._xml_validators[self._KEY_USER_DEFINED]
        else:
            version = version or self._get_version(doc)
            stix.check_version(version)
            validator = self._xml_validators[version]

        results = validator.validate(root, schemaloc)
        return results
    def _build_include_graph(self, schema_paths):
        """Builds a graph of ``xs:include`` directive sources and targets for
        the schemas contained by the `schema_paths` list.

        Args:
            schema_paths: A list of schema file paths

        Returns:
            A graph representing ``xs:include`` statements found within the
            schemas in `schema_paths`.

        """
        graph = collections.defaultdict(list)

        for fp in schema_paths:
            root = utils.get_etree_root(fp)
            includes = self._get_includes(fp, root)
            graph[fp].extend(includes)

        return graph
Exemplo n.º 27
0
    def validate(self, doc):
        """Validates an XML instance document `doc` using Schematron rules.

        Args:
            doc: An XML instance document. This can be a filename, file-like
                object, ``etree._Element`` or ``etree._ElementTree`` instance.

        Returns:
            An instance of
            :class:`.SchematronValidationResults`.

        Raises:
              .ValidationError: If there are any issues parsing `doc`.

        """
        root = utils.get_etree_root(doc)
        is_valid = self.schematron.validate(root)
        svrl_report = self.schematron.validation_report

        return SchematronValidationResults(is_valid, root, svrl_report)
Exemplo n.º 28
0
    def _build_include_graph(self, schema_paths):
        """Builds a graph of ``xs:include`` directive sources and targets for
        the schemas contained by the `schema_paths` list.

        Args:
            schema_paths: A list of schema file paths

        Returns:
            A graph representing ``xs:include`` statements found within the
            schemas in `schema_paths`.

        """
        graph = collections.defaultdict(list)

        for fp in schema_paths:
            root = utils.get_etree_root(fp)
            includes = self._get_includes(fp, root)
            graph[fp].extend(includes)

        return graph
Exemplo n.º 29
0
def get_version(doc):
    """Returns the version of a STIX instnace document.

    Args:
        doc: A STIX filename, file-like object, etree._Element or
            etree._ElementTree instance.

    Returns:
        The version of the document.

    Raises:
        .UnknownSTIXVersionError: If the document does not contain a
            ``version`` attribute on the root node.
        .ValidationError: If there are any issues parsing `doc`.
    """
    root = utils.get_etree_root(doc)

    try:
        return root.attrib['version']
    except KeyError:
        error = "Document did not contain a 'version' attribute"
        raise errors.UnknownSTIXVersionError(error)
Exemplo n.º 30
0
    def validate(self, doc, version=None):
        """Checks that a STIX document aligns with `suggested authoring
        practices`_.

        .. _suggested authoring practices: http://stixproject.github.io/documentation/suggested-practices/

        Args:
            doc: The STIX document. Can be a filename, file-like object,
                lxml._Element, or lxml._ElementTree instance.
            version: The version of the STIX document. This will determine the
                set of best practice rules to check. If ``None`` an attempt
                will be made to extract the version from `doc`.

        Returns:
            An instance of
            :class:`.BestPracticeValidationResults`.

        Raises:
            .UnknownSTIXVersionError: If `version` was ``None`` and `doc`
                did not contain any version information.
            .InvalidSTIXVersionError: If discovered version or `version`
                argument contains an invalid STIX version number.
            .ValidationError: If there are any issues parsing `doc`.

        """
        # Get the element for the input document
        root = utils.get_etree_root(doc)

        # Get the STIX version for the input `doc` if one is not passed in.
        version = version or common.get_version(root)

        # Check that the version number is a valid STIX version number
        common.check_version(version)

        # Run the best practice checks applicable for the STIX version number.
        results = self._run_rules(root, version)

        # Return the results
        return results
Exemplo n.º 31
0
    def validate(self, doc):
        """Validates an XML instance document `doc` using Schematron rules.

        Args:
            doc: An XML instance document. This can be a filename, file-like
                object, ``etree._Element`` or ``etree._ElementTree`` instance.

        Returns:
            An instance of
            :class:`.SchematronValidationResults`.

        Raises:
              .ValidationError: If there are any issues parsing `doc`.

        """
        root = utils.get_etree_root(doc)
        is_valid = self._schematron.validate(root)
        svrl_report = self._schematron.validation_report

        return SchematronValidationResults(is_valid=is_valid,
                                           doc=root,
                                           svrl_report=svrl_report)
Exemplo n.º 32
0
    def _build_schematron(self, sch, phase=None):
        """Attempts to build an ``lxml.isoschematron.Schematron`` instance
        from `sch`.

        Args:
            sch: A Schematron document filename, file-like object,
                etree._Element, or etree._ElementTree.

        Returns:
            A ``lxml.isoschematron.Schematron`` instance for `sch`.

        """
        if sch is None:
            raise ValueError("Input schematron document cannot be None")

        root = utils.get_etree_root(sch)
        schematron = lxml.isoschematron.Schematron(root,
                                                   phase=phase,
                                                   store_report=True,
                                                   store_xslt=True,
                                                   store_schematron=True)

        return schematron
Exemplo n.º 33
0
    def validate(self, doc, schemaloc=False):
        """Validates an XML instance document.

        Args:
            doc: An XML instance document. This can be a filename, file-like
                object, ``etree._Element``, or ``etree._ElementTree``.
            schemaloc: If ``True``, the document will be validated using the
                ``xsi:schemaLocation`` attribute found on the instance
                document root.

        Returns:
            An instance of
            :class:`.XmlValidationResults`.

        Raises:
            .ValidationError: If the class was not initialized with a
                schema directory and `schemaloc` is ``False`` or if there are
                any issues parsing `doc`.
            .XMLSchemaIncludeError: If an error occurs while processing the
                schemas required for validation.
            .XMLSchemaIncludeError: If an error occurs while processing
                ``xs:include`` directives.

        """
        if not (schemaloc or self._schemalocs):
            raise errors.ValidationError(
                "No schemas to validate against! Try instantiating "
                "XmlValidator with use_schemaloc=True or setting the "
                "schema_dir param in __init__"
            )

        root = utils.get_etree_root(doc)
        xsd = self._build_uber_schema(root, schemaloc)
        is_valid = xsd.validate(root)

        return XmlValidationResults(is_valid, xsd.error_log)
    def validate(self, doc, schemaloc=False):
        """Validates an XML instance document.

        Args:
            doc: An XML instance document. This can be a filename, file-like
                object, ``etree._Element``, or ``etree._ElementTree``.
            schemaloc: If ``True``, the document will be validated using the
                ``xsi:schemaLocation`` attribute found on the instance
                document root.

        Returns:
            An instance of
            :class:`.XmlValidationResults`.

        Raises:
            .ValidationError: If the class was not initialized with a
                schema directory and `schemaloc` is ``False`` or if there are
                any issues parsing `doc`.
            .XMLSchemaIncludeError: If an error occurs while processing the
                schemas required for validation.
            .XMLSchemaIncludeError: If an error occurs while processing
                ``xs:include`` directives.

        """
        if not (schemaloc or self._schemalocs):
            raise errors.ValidationError(
                "No schemas to validate against! Try instantiating "
                "XmlValidator with use_schemaloc=True or setting the "
                "schema_dir param in __init__"
            )

        root = utils.get_etree_root(doc)
        xsd = self._build_uber_schema(root, schemaloc)
        is_valid = xsd.validate(root)

        return XmlValidationResults(is_valid, xsd.error_log)
Exemplo n.º 35
0
 def test_get_schemaloc_pairs_raises(self):
     sio = StringIO(XML)
     root = utils.get_etree_root(sio)
     self.assertRaises(KeyError, utils.get_schemaloc_pairs, root)
Exemplo n.º 36
0
 def test_get_schemaloc_pairs(self):
     sio = StringIO(XML_SCHEMALOC)
     root = utils.get_etree_root(sio)
     pairs = utils.get_schemaloc_pairs(root)
     self.assertEqual(2, len(pairs))
Exemplo n.º 37
0
 def test_get_etree_root_elementree(self):
     tree = etree.fromstring(XML)
     root = utils.get_etree_root(tree)
     lname = etree.QName(root).localname
     self.assertEqual(lname, XML_ROOT_LOCALNAME)
Exemplo n.º 38
0
 def test_get_etree_root_stringio(self):
     sio = StringIO(XML)
     root = utils.get_etree_root(sio)
     lname = etree.QName(root).localname
     self.assertEqual(lname, XML_ROOT_LOCALNAME)
Exemplo n.º 39
0
 def test_get_etree_root_elementree(self):
     tree = etree.fromstring(XML)
     root = utils.get_etree_root(tree)
     lname = etree.QName(root).localname
     self.assertEqual(lname, XML_ROOT_LOCALNAME)
Exemplo n.º 40
0
 def test_get_schemaloc_pairs(self):
     sio = StringIO(XML_SCHEMALOC)
     root = utils.get_etree_root(sio)
     pairs = utils.get_schemaloc_pairs(root)
     self.assertEqual(2, len(list(pairs)))
Exemplo n.º 41
0
 def test_get_etree_root_stringio(self):
     sio = StringIO(XML)
     root = utils.get_etree_root(sio)
     lname = etree.QName(root).localname
     self.assertEqual(lname, XML_ROOT_LOCALNAME)