From fc3141283de7ff5409885b4e9fea12456520689a Mon Sep 17 00:00:00 2001 From: Davide Brunato Date: Thu, 14 Nov 2019 11:20:26 +0100 Subject: [PATCH] Fix some W3C failed tests - fix inherited attrs composition in XSD elements - check single ID for element's attributes validation --- xmlschema/validators/attributes.py | 6 ++++++ xmlschema/validators/complex_types.py | 2 +- xmlschema/validators/elements.py | 9 ++++----- xmlschema/validators/groups.py | 2 +- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/xmlschema/validators/attributes.py b/xmlschema/validators/attributes.py index 051d69d..cbdc1e9 100644 --- a/xmlschema/validators/attributes.py +++ b/xmlschema/validators/attributes.py @@ -600,6 +600,8 @@ class XsdAttributeGroup(MutableMapping, XsdComponent, ValidationMixin): kwargs['level'] = kwargs.get('level', 0) + 1 use_defaults = kwargs.get('use_defaults', True) + id_map = kwargs.get('id_map', '') + num_id = len(id_map) additional_attrs = [(k, v) for k, v in self.iter_predefined(use_defaults) if k not in attrs] if additional_attrs: @@ -644,6 +646,10 @@ class XsdAttributeGroup(MutableMapping, XsdComponent, ValidationMixin): result_list.append((name, result)) break + if self.xsd_version == '1.0' and len(id_map) - num_id > 1: + reason = "No more than one attribute of type ID should be present in an element" + yield self.validation_error(validation, reason, attrs, **kwargs) + if kwargs.get('fill_missing') is True: if filler is None: result_list.extend((k, None) for k in self._attribute_group diff --git a/xmlschema/validators/complex_types.py b/xmlschema/validators/complex_types.py index 86ef0cc..4010445 100644 --- a/xmlschema/validators/complex_types.py +++ b/xmlschema/validators/complex_types.py @@ -502,7 +502,7 @@ class XsdComplexType(XsdType, ValidationMixin): elif other.name == XSD_ANY_TYPE: return True elif self.base_type is other: - return derivation is None or self.base_type.derivation == derivation + return derivation is None # or self.base_type.derivation == derivation elif hasattr(other, 'member_types'): return any(self.is_derived(m, derivation) for m in other.member_types) elif self.base_type is None: diff --git a/xmlschema/validators/elements.py b/xmlschema/validators/elements.py index ba5a8b0..4b2d3c7 100644 --- a/xmlschema/validators/elements.py +++ b/xmlschema/validators/elements.py @@ -21,7 +21,7 @@ from ..exceptions import XMLSchemaAttributeError from ..qnames import XSD_ANNOTATION, XSD_GROUP, XSD_SEQUENCE, XSD_ALL, \ XSD_CHOICE, XSD_ATTRIBUTE_GROUP, XSD_COMPLEX_TYPE, XSD_SIMPLE_TYPE, \ XSD_ALTERNATIVE, XSD_ELEMENT, XSD_ANY_TYPE, XSD_UNIQUE, XSD_KEY, \ - XSD_KEYREF, XSI_NIL, XSI_TYPE, XSD_ID, XSD_ERROR, get_qname + XSD_KEYREF, XSI_NIL, XSI_TYPE, XSD_ERROR, get_qname from ..etree import etree_element from ..helpers import get_xsd_derivation_attribute, get_xsd_form_attribute, \ ParticleCounter, strictly_equal @@ -244,15 +244,13 @@ class XsdElement(XsdComponent, ValidationMixin, ParticleMixin, ElementPathMixin) if not self.type.is_valid(attrib['default']): msg = "'default' value {!r} is not compatible with the type {!r}" self.parse_error(msg.format(attrib['default'], self.type)) - elif self.xsd_version == '1.0' and ( - self.type.name == XSD_ID or self.type.is_derived(self.schema.meta_schema.types['ID'])): + elif self.xsd_version == '1.0' and self.type.is_key(): self.parse_error("'xs:ID' or a type derived from 'xs:ID' cannot has a 'default'") elif 'fixed' in attrib: if not self.type.is_valid(attrib['fixed']): msg = "'fixed' value {!r} is not compatible with the type {!r}" self.parse_error(msg.format(attrib['fixed'], self.type)) - elif self.xsd_version == '1.0' and ( - self.type.name == XSD_ID or self.type.is_derived(self.schema.meta_schema.types['ID'])): + elif self.xsd_version == '1.0' and self.type.is_key(): self.parse_error("'xs:ID' or a type derived from 'xs:ID' cannot has a 'default'") return 0 @@ -963,6 +961,7 @@ class Xsd11Element(XsdElement): if inherited: dummy = etree_element('_dummy_element', attrib=inherited) + dummy.attrib.update(elem.attrib) for alt in filter(lambda x: x.type is not None, self.alternatives): if alt.token is None or alt.test(elem) or alt.test(dummy): diff --git a/xmlschema/validators/groups.py b/xmlschema/validators/groups.py index 2684135..f3fa2ce 100644 --- a/xmlschema/validators/groups.py +++ b/xmlschema/validators/groups.py @@ -486,7 +486,7 @@ class XsdGroup(XsdComponent, ModelGroup, ValidationMixin): if 'substitution' in model_element.block \ or xsd_element.type.is_blocked(model_element): raise XMLSchemaValidationError( - model_element, "substitution of %r is blocked" % model_element + model_element, elem, "substitution of %r is blocked" % model_element ) alternatives = ()