class XsdFieldSelector(XsdSelector): """Class for defining an XPath field selector for an XSD identity constraint.""" _ADMITTED_TAGS = {XSD_FIELD} pattern = translate_pattern( r"(\.//)?((((child::)?((\i\c*:)?(\i\c*|\*)))|\.)/)*((((child::)?" r"((\i\c*:)?(\i\c*|\*)))|\.)|((attribute::|@)((\i\c*:)?(\i\c*|\*))))" r"(\|(\.//)?((((child::)?((\i\c*:)?(\i\c*|\*)))|\.)/)*" r"((((child::)?((\i\c*:)?(\i\c*|\*)))|\.)|" r"((attribute::|@)((\i\c*:)?(\i\c*|\*)))))*", back_references=False, lazy_quantifiers=False, anchors=False)
def _parse_value(self, elem): try: python_pattern = translate_pattern(pattern=elem.attrib['value'], xsd_version=self.xsd_version, back_references=False, lazy_quantifiers=False, anchors=False) return re.compile(python_pattern) except KeyError: self.parse_error("missing 'value' attribute", elem) return re.compile(r'^.*$') except (RegexError, re.error, XMLSchemaDecodeError) as err: self.parse_error(err, elem) return re.compile(r'^.*$')
class XsdSelector(XsdComponent): """Class for defining an XPath selector for an XSD identity constraint.""" _ADMITTED_TAGS = {XSD_SELECTOR} xpath_default_namespace = '' pattern = translate_pattern( r"(\.//)?(((child::)?((\i\c*:)?(\i\c*|\*)))|\.)(/(((child::)?" r"((\i\c*:)?(\i\c*|\*)))|\.))*(\|(\.//)?(((child::)?((\i\c*:)?" r"(\i\c*|\*)))|\.)(/(((child::)?((\i\c*:)?(\i\c*|\*)))|\.))*)*", back_references=False, lazy_quantifiers=False, anchors=False) token = None parser = None def __init__(self, elem, schema, parent): super(XsdSelector, self).__init__(elem, schema, parent) def _parse(self): super(XsdSelector, self)._parse() try: self.path = self.elem.attrib['xpath'] except KeyError: self.parse_error("'xpath' attribute required") self.path = '*' else: try: match = self.pattern.match(self.path.replace(' ', '')) except AttributeError: # Compile regex pattern self.__class__.pattern = re.compile(self.pattern) match = self.pattern.match(self.path.replace(' ', '')) if not match: msg = "invalid XPath expression for an {}" self.parse_error(msg.format(self.__class__.__name__)) # XSD 1.1 xpathDefaultNamespace attribute if self.schema.XSD_VERSION > '1.0': if 'xpathDefaultNamespace' in self.elem.attrib: self.xpath_default_namespace = self._parse_xpath_default_namespace( self.elem) else: self.xpath_default_namespace = self.schema.xpath_default_namespace self.parser = IdentityXPathParser( namespaces=self.namespaces, strict=False, compatibility_mode=True, default_namespace=self.xpath_default_namespace, ) try: self.token = self.parser.parse(self.path) except ElementPathError as err: self.token = self.parser.parse('*') self.parse_error(err) def __repr__(self): return '%s(path=%r)' % (self.__class__.__name__, self.path) @property def built(self): return self.token is not None @property def target_namespace(self): # TODO: implement a property in elementpath for getting XPath token's namespace if self.token is None: pass # xpathDefaultNamespace="##targetNamespace" elif self.token.symbol == ':': return self.token[1].namespace or self.xpath_default_namespace elif self.token.symbol == '@' and self.token[0].symbol == ':': return self.token[0][1].namespace or self.xpath_default_namespace return self.schema.target_namespace
class XsdSelector(XsdComponent): """Class for defining an XPath selector for an XSD identity constraint.""" _ADMITTED_TAGS = {XSD_SELECTOR} xpath_default_namespace = '' pattern = translate_pattern( r"(\.//)?(((child::)?((\i\c*:)?(\i\c*|\*)))|\.)(/(((child::)?" r"((\i\c*:)?(\i\c*|\*)))|\.))*(\|(\.//)?(((child::)?((\i\c*:)?" r"(\i\c*|\*)))|\.)(/(((child::)?((\i\c*:)?(\i\c*|\*)))|\.))*)*", back_references=False, lazy_quantifiers=False, anchors=False ) token = None parser = None def __init__(self, elem, schema, parent): super(XsdSelector, self).__init__(elem, schema, parent) def _parse(self): super(XsdSelector, self)._parse() try: self.path = self.elem.attrib['xpath'] except KeyError: self.parse_error("'xpath' attribute required:", self.elem) self.path = '*' else: try: if not self.pattern.match(self.path.replace(' ', '')): self.parse_error("invalid XPath expression for an {}".format(type(self))) except AttributeError: # Compile regex pattern self.__class__.pattern = re.compile(self.pattern) if not self.pattern.match(self.path.replace(' ', '')): self.parse_error("invalid XPath expression for an {}".format(type(self))) # XSD 1.1 xpathDefaultNamespace attribute if self.schema.XSD_VERSION > '1.0': if 'xpathDefaultNamespace' in self.elem.attrib: self.xpath_default_namespace = self._parse_xpath_default_namespace(self.elem) else: self.xpath_default_namespace = self.schema.xpath_default_namespace self.parser = IdentityXPathParser( namespaces=self.namespaces, strict=False, compatibility_mode=True, default_namespace=self.xpath_default_namespace, ) try: self.token = self.parser.parse(self.path) except ElementPathError as err: self.parse_error(err) self.token = self.parser.parse('*') def __repr__(self): return '%s(path=%r)' % (self.__class__.__name__, self.path) @property def built(self): return self.token is not None @property def target_namespace(self): if ':' in self.path: match = QNAME_PATTERN.findall(self.path) if match is not None: prefix = match[0][0] if prefix: return self.namespaces[prefix] elif self.xpath_default_namespace: return self.xpath_default_namespace return self.schema.target_namespace