Ejemplo n.º 1
0
    def test_local_name_functions(self):
        self.assertEqual(local_name(XSD_SCHEMA), 'schema')
        self.assertEqual(local_name('schema'), 'schema')
        self.assertEqual(local_name(''), '')
        self.assertEqual(local_name(None), None)

        self.assertRaises(ValueError, local_name, '{ns name')
        self.assertRaises(TypeError, local_name, 1.0)
        self.assertRaises(TypeError, local_name, 0)
Ejemplo n.º 2
0
def iterchildren_by_tag(tag):
    """
    Defines a generator that produce all child elements that have a specific tag.
    """
    def iterfind_function(elem):
        for e in elem:
            if e.tag == tag:
                yield e

    iterfind_function.__name__ = str(
        'iterfind_xsd_%ss' %
        '_'.join(camel_case_split(local_name(tag))).lower())
    return iterfind_function
Ejemplo n.º 3
0
 def __setattr__(self, name, value):
     if name == "elem":
         if not is_etree_element(value):
             raise XMLSchemaTypeError(
                 "%r attribute must be an Etree Element: %r" %
                 (name, value))
         elif value.tag not in self._admitted_tags:
             raise XMLSchemaValueError(
                 "wrong XSD element %r for %r, must be one of %r." %
                 (local_name(value.tag), self,
                  [local_name(tag) for tag in self._admitted_tags]))
         super(XsdComponent, self).__setattr__(name, value)
         self._parse()
         return
     elif name == "schema":
         if hasattr(
                 self, 'schema'
         ) and self.schema.target_namespace != value.target_namespace:
             raise XMLSchemaValueError(
                 "cannot change 'schema' attribute of %r: the actual %r has a different "
                 "target namespace than %r." % (self, self.schema, value))
     super(XsdComponent, self).__setattr__(name, value)
Ejemplo n.º 4
0
    def _parse_content_model(self, elem, content_model):
        self.model = local_name(content_model.tag)
        if self.model == 'all':
            if self.max_occurs != 1:
                self.parse_error("maxOccurs must be 1 for 'all' model groups")
            if self.min_occurs not in (0, 1):
                self.parse_error(
                    "minOccurs must be (0 | 1) for 'all' model groups")

        for child in self._iterparse_components(content_model):
            if child.tag == XSD_ELEMENT:
                # Builds inner elements and reference groups later, for avoids circularity.
                self.append((child, self.schema))
            elif content_model.tag == XSD_ALL:
                self.parse_error("'all' model can contains only elements.",
                                 elem)
            elif child.tag == XSD_ANY:
                self.append(XsdAnyElement(child, self.schema, self))
            elif child.tag in (XSD_SEQUENCE, XSD_CHOICE):
                self.append(XsdGroup(child, self.schema, self))
            elif child.tag == XSD_GROUP:
                try:
                    ref = self.schema.resolve_qname(child.attrib['ref'])
                except KeyError:
                    self.parse_error("missing attribute 'ref' in local group",
                                     child)
                    continue

                if ref != self.name:
                    xsd_group = XsdGroup(child, self.schema, self)
                    if xsd_group.model == 'all':
                        self.parse_error(
                            "'all' model can appears only at 1st level of a model group"
                        )
                    else:
                        self.append(xsd_group)
                elif self.redefine is None:
                    self.parse_error(
                        "Circular definition detected for group %r:" %
                        self.ref, elem)
                else:
                    if child.get('minOccurs', '1') != '1' or child.get(
                            'maxOccurs', '1') != '1':
                        self.parse_error(
                            "Redefined group reference cannot have minOccurs/maxOccurs other than 1:",
                            elem)
                    self.append(self.redefine)
            else:
                continue  # Error already caught by validation against the meta-schema
Ejemplo n.º 5
0
    def _parse_derivation_elem(self, elem):
        derivation_elem = self._parse_component(elem, required=False)
        if getattr(derivation_elem, 'tag',
                   None) not in (XSD_RESTRICTION, XSD_EXTENSION):
            self.parse_error("restriction or extension tag expected",
                             derivation_elem)
            self.content_type = self.schema.create_any_content_group(self)
            self.attributes = self.schema.create_any_attribute_group(self)
            return

        derivation = local_name(derivation_elem.tag)
        if self._derivation is None:
            self._derivation = derivation == 'extension'
        elif self.redefine is None:
            raise XMLSchemaValueError(
                "%r is expected to have a redefined/overridden component" %
                self)

        if self.base_type is not None and derivation in self.base_type.final:
            self.parse_error("%r derivation not allowed for %r." %
                             (derivation, self))
        return derivation_elem
Ejemplo n.º 6
0
    def load_xsd_globals(xsd_globals, schemas):
        redefinitions = []
        for schema in schemas:
            target_namespace = schema.target_namespace
            for elem in iterchildren_xsd_redefine(schema.root):
                location = elem.get('schemaLocation')
                if location is None:
                    continue
                for child in filter_function(elem):
                    qname = get_qname(target_namespace, child.attrib['name'])
                    redefinitions.append(
                        (qname, child, schema, schema.includes[location]))

            for elem in filter_function(schema.root):
                qname = get_qname(target_namespace, elem.attrib['name'])
                try:
                    xsd_globals[qname].append((elem, schema))
                except KeyError:
                    xsd_globals[qname] = (elem, schema)
                except AttributeError:
                    xsd_globals[qname] = [xsd_globals[qname], (elem, schema)]

        tags = Counter([x[0] for x in redefinitions])
        for qname, elem, schema, redefined_schema in redefinitions:

            # Checks multiple redefinitions
            if tags[qname] > 1:
                tags[qname] = 1

                redefined_schemas = [
                    x[3] for x in redefinitions if x[0] == qname
                ]
                if any(
                        redefined_schemas.count(x) > 1
                        for x in redefined_schemas):
                    schema.parse_error(
                        "multiple redefinition for {} {!r}".format(
                            local_name(elem.tag), qname), elem)
                else:
                    redefined_schemas = {
                        x[3]: x[2]
                        for x in redefinitions if x[0] == qname
                    }
                    for rs, s in redefined_schemas.items():
                        while True:
                            try:
                                s = redefined_schemas[s]
                            except KeyError:
                                break

                            if s is rs:
                                schema.parse_error(
                                    "circular redefinition for {} {!r}".format(
                                        local_name(elem.tag), qname), elem)
                                break

            # Append redefinition
            try:
                xsd_globals[qname].append((elem, schema))
            except KeyError:
                schema.parse_error("not a redefinition!", elem)
                # xsd_globals[qname] = elem, schema
            except AttributeError:
                xsd_globals[qname] = [xsd_globals[qname], (elem, schema)]
Ejemplo n.º 7
0
 def local_name(self):
     return local_name(self.name)