def stepAxis(self, op, p, sourceSequence): targetSequence = [] for node in sourceSequence: if not isinstance(node,(ModelObject, etree._ElementTree, ModelAttribute)): raise XPathException(self.progHeader, 'err:XPTY0020', _('Axis step {0} context item is not a node: {1}').format(op, node)) targetNodes = [] if isinstance(p,QNameDef): ns = p.namespaceURI; localname = p.localName if p.isAttribute: if isinstance(node,ModelObject): attrTag = p.localName if p.unprefixed else p.clarkNotation modelAttribute = None try: modelAttribute = node.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): # may be lax or deferred validated try: validate(node.modelXbrl, node, p) modelAttribute = node.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): pass if modelAttribute is None: value = node.get(attrTag) if value is not None: targetNodes.append(ModelAttribute(node,p.clarkNotation,UNKNOWN,value,value,value)) elif modelAttribute.xValid >= VALID: targetNodes.append(modelAttribute) elif op == '/' or op is None: if isinstance(node,(ModelObject, etree._ElementTree)): targetNodes = XmlUtil.children(node, ns, localname) elif op == '//': if isinstance(node,(ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants(node, ns, localname) elif op == '..': if isinstance(node,ModelAttribute): targetNodes = [ node.modelElement ] else: targetNodes = [ XmlUtil.parent(node) ] elif isinstance(p, OperationDef) and isinstance(p.name,QNameDef): if isinstance(node,ModelObject): if p.name.localName == "text": targetNodes = [XmlUtil.text(node)] # todo: add element, attribute, node, etc... elif p == '*': # wildcard if op == '/' or op is None: if isinstance(node,(ModelObject, etree._ElementTree)): targetNodes = XmlUtil.children(node, '*', '*') elif op == '//': if isinstance(node,(ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants(node, '*', '*') targetSequence.extend(targetNodes) return targetSequence
def element_attribute(element, attrQname): attrTag = attrQname.clarkNotation modelAttribute = None try: modelAttribute = element.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): # may be lax or deferred validated try: validate(element.modelXbrl, element, attrQname) modelAttribute = element.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): pass if modelAttribute is None: value = element.get(attrTag) if value is not None: return value elif modelAttribute.xValid >= VALID: return modelAttribute.xValue return ()
def validateElementSequence(modelXbrl, compositor, children, ixFacts, iNextChild=0): particles = compositor.dereference().particles iStartingChild = iNextChild errDesc = None if isinstance(compositor, ModelAll): allParticles = set() # elements required iNextAfterAll = iStartingChild elif isinstance(compositor, ModelChoice): anyChoiceHasMinOccurs0 = False moreParticlesPasses = True while moreParticlesPasses: moreParticlesPasses = False for particle in particles: occurences = 0 if isinstance(particle, (ModelConcept, ModelAny)): elementDeclaration = particle.dereference() while iNextChild < len(children): elt = children[iNextChild] vQname = elt.vQname(modelXbrl) # takes care of elements inside inline or other instances if isinstance(elt, ModelObject): # for any, check namespace overlap if ((isinstance(particle, ModelAny) and particle.allowsNamespace(vQname.namespaceURI)) or (isinstance(particle, ModelConcept) and elementDeclaration is not None and (vQname == elementDeclaration.qname or elt.elementDeclaration(modelXbrl).substitutesForQname(elementDeclaration.qname)))): occurences += 1 validate(modelXbrl, elt, ixFacts=ixFacts) iNextChild += 1 if occurences == particle.maxOccurs: break elif not isinstance(particle, ModelAll): break # done with this element else: # comment or processing instruction, skip over it iNextChild += 1 else: # group definition or compositor while occurences < particle.maxOccurs: iPrevChild = iNextChild iNextChild, occured, errDesc, errArgs = validateElementSequence(modelXbrl, particle, children, ixFacts, iNextChild) if occured: # test if occurence was because of minOccurs zero but no match occured (HF 2012-09-07) if occured and iNextChild == iPrevChild and particle.minOccurs == 0: # nothing really occured break occurences += 1 if occurences == particle.maxOccurs or iNextChild >= len(children): break else: break if isinstance(compositor, ModelChoice): if occurences > 0 and particle.minOccurs <= occurences <= particle.maxOccurs: return (iNextChild, True, None, None) # choice has been selected else: # otherwise start again on next choice if particle.minOccurs == 0: anyChoiceHasMinOccurs0 = True iNextChild = iStartingChild elif isinstance(compositor, ModelAll): if particle.minOccurs <= occurences <= particle.maxOccurs: allParticles.add(particle) # particle found moreParticlesPasses = True break # advance to next all particle elif particle.minOccurs > 0 and errDesc: return (iNextChild, False, errDesc, errArgs) elif not particle.minOccurs <= occurences <= particle.maxOccurs: return (iNextChild, False, ("xmlSchema:elementOccurencesError", _("%(compositor)s(%(particles)s) %(element)s occured %(occurences)s times, minOccurs=%(minOccurs)s, maxOccurs=%(maxOccurs)s, within %(parentElement)s")), dict(compositor=compositor, particles=particles, occurences=occurences, minOccurs=particle.minOccursStr, maxOccurs=particle.maxOccursStr)) if isinstance(compositor, ModelAll): missingParticles = set(particles) - allParticles if missingParticles: return (iNextChild, False, ("xmlSchema:missingParticlesError", _("All(%(particles)s) missing at %(element)s, within %(parentElement)s")), dict(particles=particles)) occured = True elif isinstance(compositor, ModelChoice): occured = anyChoiceHasMinOccurs0 # deemed to have occured if any choice had minoccurs=0 else: occured = True if isinstance(compositor, ModelType) and iNextChild < len(children): #elt = children[iNextChild] #eltChildren = elt.modelTupleFacts if ixFacts else elt #if any(True for child in eltChildren if isinstance(child, ModelObject)): # any unexpected content elements if any(True for child in children[iNextChild:] if isinstance(child, ModelObject)): # any unexpected content elements return (iNextChild, False, ("xmlSchema:elementUnexpected", _("%(compositor)s(%(particles)s) %(element)s unexpected, within %(parentElement)s")), dict(compositor=compositor, particles=particles)) return (iNextChild, occured, None, None)
def stepAxis(self, op, p, sourceSequence): targetSequence = [] for node in sourceSequence: if not isinstance( node, (ModelObject, etree._ElementTree, ModelAttribute)): raise XPathException( self.progHeader, 'err:XPTY0020', _('Axis step {0} context item is not a node: {1}').format( op, node)) targetNodes = [] if isinstance(p, QNameDef): ns = p.namespaceURI localname = p.localName axis = p.axis if p.isAttribute: if isinstance(node, ModelObject): attrTag = p.localName if p.unprefixed else p.clarkNotation modelAttribute = None try: modelAttribute = node.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): # may be lax or deferred validated try: validate(node.modelXbrl, node, p) modelAttribute = node.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): pass if modelAttribute is None: value = node.get(attrTag) if value is not None: targetNodes.append( ModelAttribute(node, p.clarkNotation, UNKNOWN, value, value, value)) elif modelAttribute.xValid >= VALID: targetNodes.append(modelAttribute) elif op == '/' or op is None: if axis is None or axis == "child": if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.children(node, ns, localname) elif axis == "parent": if isinstance(node, ModelAttribute): parentNode = [node.modelElement] else: parentNode = [XmlUtil.parent(node)] if (isinstance(node, ModelObject) and (not ns or ns == parentNode.namespaceURI or ns == "*") and (localname == parentNode.localName or localname == "*")): targetNodes = [parentNode] elif axis == "self": if (isinstance(node, ModelObject) and (not ns or ns == node.namespaceURI or ns == "*") and (localname == node.localName or localname == "*")): targetNodes = [node] elif axis.startswith("descendant"): if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants( node, ns, localname) if (axis.endswith("-or-self") and isinstance(node, ModelObject) and (not ns or ns == node.namespaceURI or ns == "*") and (localname == node.localName or localname == "*")): targetNodes.append(node) elif axis.startswith("ancestor"): if isinstance(node, ModelObject): targetNodes = [ ancestor for ancestor in XmlUtil.ancestors(node) if ((not ns or ns == ancestor.namespaceURI or ns == "*") and ( localname == ancestor.localName or localname == "*")) ] if (axis.endswith("-or-self") and isinstance(node, ModelObject) and (not ns or ns == node.namespaceURI or ns == "*") and (localname == node.localName or localname == "*")): targetNodes.insert(0, node) elif axis.endswith("-sibling"): if isinstance(node, ModelObject): targetNodes = [ sibling for sibling in node.itersiblings( preceding=axis.startswith("preceding")) if ((not ns or ns == sibling.namespaceURI or ns == "*") and ( localname == sibling.localName or localname == "*")) ] elif axis == "preceding": if isinstance(node, ModelObject): for preceding in node.getroottree().iter(): if preceding == node: break elif ((not ns or ns == preceding.namespaceURI or ns == "*") and (localname == preceding.localName or localname == "*")): targetNodes.append(preceding) elif axis == "following": if isinstance(node, ModelObject): foundNode = False for following in node.getroottree().iter(): if following == node: foundNode = True elif (foundNode and (not ns or ns == following.namespaceURI or ns == "*") and (localname == following.localName or localname == "*")): targetNodes.append(following) elif op == '//': if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants(node, ns, localname) elif op == '..': if isinstance(node, ModelAttribute): targetNodes = [node.modelElement] else: targetNodes = [XmlUtil.parent(node)] elif isinstance(p, OperationDef) and isinstance(p.name, QNameDef): if isinstance(node, ModelObject): if p.name.localName == "text": # note this is not string value, just child text targetNodes = [node.textValue] # todo: add element, attribute, node, etc... elif p == '*': # wildcard if op == '/' or op is None: if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.children(node, '*', '*') elif op == '//': if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants(node, '*', '*') targetSequence.extend(targetNodes) return targetSequence
def validateElementSequence(modelXbrl, compositor, children, ixFacts, iNextChild=0): particles = compositor.dereference().particles iStartingChild = iNextChild errDesc = None if isinstance(compositor, ModelAll): allParticles = set() # elements required iNextAfterAll = iStartingChild elif isinstance(compositor, ModelChoice): anyChoiceHasMinOccurs0 = False moreParticlesPasses = True while moreParticlesPasses: moreParticlesPasses = False for particle in particles: occurrences = 0 if isinstance(particle, (ModelConcept, ModelAny)): elementDeclaration = particle.dereference() while iNextChild < len(children): elt = children[iNextChild] # children now only contains ModelObjects, no comments or other lxml elements vQname = elt.vQname(modelXbrl) # takes care of elements inside inline or other instances # for any, check namespace overlap if ((isinstance(particle, ModelAny) and particle.allowsNamespace(vQname.namespaceURI)) or (isinstance(particle, ModelConcept) and elementDeclaration is not None and (vQname == elementDeclaration.qname or (vQname in modelXbrl.qnameConcepts and modelXbrl.qnameConcepts[vQname].substitutesForQname(elementDeclaration.qname))))): occurrences += 1 validate(modelXbrl, elt, ixFacts=ixFacts) iNextChild += 1 if occurrences == particle.maxOccurs: break elif not isinstance(particle, ModelAll): break # done with this element else: # group definition or compositor while occurrences < particle.maxOccurs: iPrevChild = iNextChild iNextChild, occurred, errDesc, errArgs = validateElementSequence(modelXbrl, particle, children, ixFacts, iNextChild) if occurred: # test if occurrence was because of minOccurs zero but no match occurred (HF 2012-09-07) if occurred and iNextChild == iPrevChild and particle.minOccurs == 0: # nothing really occurred break occurrences += 1 if occurrences == particle.maxOccurs or iNextChild >= len(children): break else: break if isinstance(compositor, ModelChoice): if occurrences > 0 and particle.minOccurs <= occurrences <= particle.maxOccurs: return (iNextChild, True, None, None) # choice has been selected else: # otherwise start again on next choice if particle.minOccurs == 0: anyChoiceHasMinOccurs0 = True iNextChild = iStartingChild elif isinstance(compositor, ModelAll): if particle.minOccurs <= occurrences <= particle.maxOccurs: allParticles.add(particle) # particle found moreParticlesPasses = True break # advance to next all particle elif particle.minOccurs > 0 and errDesc: return (iNextChild, False, errDesc, errArgs) elif not particle.minOccurs <= occurrences <= particle.maxOccurs: return (iNextChild, False, ("xmlSchema:elementOccurrencesError", _("%(compositor)s(%(particles)s) %(element)s occurred %(occurrences)s times, minOccurs=%(minOccurs)s, maxOccurs=%(maxOccurs)s, within %(parentElement)s") if occurrences > 0 else _("%(compositor)s(%(particles)s) content occurred %(occurrences)s times, minOccurs=%(minOccurs)s, maxOccurs=%(maxOccurs)s, within %(parentElement)s") ), dict(compositor=compositor, particles=particles, occurrences=occurrences, minOccurs=particle.minOccursStr, maxOccurs=particle.maxOccursStr)) if isinstance(compositor, ModelAll): missingParticles = set(particles) - allParticles if missingParticles: return (iNextChild, False, ("xmlSchema:missingParticlesError", _("All(%(particles)s) missing at %(element)s, within %(parentElement)s")), dict(particles=particles)) occurred = True elif isinstance(compositor, ModelChoice): occurred = anyChoiceHasMinOccurs0 # deemed to have occurred if any choice had minoccurs=0 else: occurred = True if isinstance(compositor, ModelType) and iNextChild < len(children): #if any(True for child in children[iNextChild:] if isinstance(child, ModelObject)): # any unexpected content elements if len(children) > iNextChild: # any unexpected content elements return (iNextChild, False, ("xmlSchema:elementUnexpected", _("%(compositor)s(%(particles)s) %(element)s unexpected, within %(parentElement)s")), dict(compositor=compositor, particles=particles)) return (iNextChild, occurred, None, None)
def stepAxis(self, op, p, sourceSequence): targetSequence = [] for node in sourceSequence: if not isinstance(node,(ModelObject, etree._ElementTree, ModelAttribute)): raise XPathException(self.progHeader, 'err:XPTY0020', _('Axis step {0} context item is not a node: {1}').format(op, node)) targetNodes = [] if isinstance(p,QNameDef): ns = p.namespaceURI; localname = p.localName; axis = p.axis if p.isAttribute: if isinstance(node,ModelObject): attrTag = p.localName if p.unprefixed else p.clarkNotation modelAttribute = None try: modelAttribute = node.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): # may be lax or deferred validated try: validate(node.modelXbrl, node, p) modelAttribute = node.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): pass if modelAttribute is None: value = node.get(attrTag) if value is not None: targetNodes.append(ModelAttribute(node,p.clarkNotation,UNKNOWN,value,value,value)) elif modelAttribute.xValid >= VALID: targetNodes.append(modelAttribute) elif op == '/' or op is None: if axis is None or axis == "child": if isinstance(node,(ModelObject, etree._ElementTree)): targetNodes = XmlUtil.children(node, ns, localname) elif axis == "parent": if isinstance(node,ModelAttribute): paretNode = [ node.modelElement ] else: parentNode = [ XmlUtil.parent(node) ] if (isinstance(node,ModelObject) and (not ns or ns == parentNode.namespaceURI or ns == "*") and (localname == parentNode.localName or localname == "*")): targetNodes = [ parentNode ] elif axis == "self": if (isinstance(node,ModelObject) and (not ns or ns == node.namespaceURI or ns == "*") and (localname == node.localName or localname == "*")): targetNodes = [ node ] elif axis.startswith("descendant"): if isinstance(node,(ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants(node, ns, localname) if (axis.endswith("-or-self") and isinstance(node,ModelObject) and (not ns or ns == node.namespaceURI or ns == "*") and (localname == node.localName or localname == "*")): targetNodes.append(node) elif axis.startswith("ancestor"): if isinstance(node,ModelObject): targetNodes = [ancestor for ancestor in XmlUtil.ancestors(node) if ((not ns or ns == ancestor.namespaceURI or ns == "*") and (localname == ancestor.localName or localname == "*"))] if (axis.endswith("-or-self") and isinstance(node,ModelObject) and (not ns or ns == node.namespaceURI or ns == "*") and (localname == node.localName or localname == "*")): targetNodes.insert(0, node) elif axis.endswith("-sibling"): if isinstance(node,ModelObject): targetNodes = [sibling for sibling in node.itersiblings(preceding=axis.startswith("preceding")) if ((not ns or ns == sibling.namespaceURI or ns == "*") and (localname == sibling.localName or localname == "*"))] elif axis == "preceding": if isinstance(node,ModelObject): for preceding in node.getroottree().iter(): if preceding == node: break elif ((not ns or ns == preceding.namespaceURI or ns == "*") and (localname == preceding.localName or localname == "*")): targetNodes.append(preceding) elif axis == "following": if isinstance(node,ModelObject): foundNode = False for following in node.getroottree().iter(): if following == node: foundNode = True elif (foundNode and (not ns or ns == following.namespaceURI or ns == "*") and (localname == following.localName or localname == "*")): targetNodes.append(following) elif op == '//': if isinstance(node,(ModelObject, etree. _ElementTree)): targetNodes = XmlUtil.descendants(node, ns, localname) elif op == '..': if isinstance(node,ModelAttribute): targetNodes = [ node.modelElement ] else: targetNodes = [ XmlUtil.parent(node) ] elif isinstance(p, OperationDef) and isinstance(p.name,QNameDef): if isinstance(node,ModelObject): if p.name.localName == "text": targetNodes = [XmlUtil.text(node)] # todo: add element, attribute, node, etc... elif p == '*': # wildcard if op == '/' or op is None: if isinstance(node,(ModelObject, etree._ElementTree)): targetNodes = XmlUtil.children(node, '*', '*') elif op == '//': if isinstance(node,(ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants(node, '*', '*') targetSequence.extend(targetNodes) return targetSequence
def stepAxis(self, op, p, sourceSequence): targetSequence = [] for node in sourceSequence: if not isinstance( node, (ModelObject, etree._ElementTree, ModelAttribute)): raise XPathException( self.progHeader, 'err:XPTY0020', _('Axis step {0} context item is not a node: {1}').format( op, node)) targetNodes = [] if isinstance(p, QNameDef): ns = p.namespaceURI localname = p.localName if p.isAttribute: if isinstance(node, ModelObject): attrTag = p.localName if p.unprefixed else p.clarkNotation modelAttribute = None try: modelAttribute = node.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): # may be lax or deferred validated try: validate(node.modelXbrl, node, p) modelAttribute = node.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): pass if modelAttribute is None: value = node.get(attrTag) if value is not None: targetNodes.append( ModelAttribute(node, p.clarkNotation, UNKNOWN, value, value, value)) elif modelAttribute.xValid >= VALID: targetNodes.append(modelAttribute) elif op == '/' or op is None: if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.children(node, ns, localname) elif op == '//': if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants(node, ns, localname) elif op == '..': if isinstance(node, ModelAttribute): targetNodes = [node.modelElement] else: targetNodes = [XmlUtil.parent(node)] elif isinstance(p, OperationDef) and isinstance(p.name, QNameDef): if isinstance(node, ModelObject): if p.name.localName == "text": targetNodes = [XmlUtil.text(node)] # todo: add element, attribute, node, etc... elif p == '*': # wildcard if op == '/' or op is None: if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.children(node, '*', '*') elif op == '//': if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants(node, '*', '*') targetSequence.extend(targetNodes) return targetSequence
def validateElementSequence(modelXbrl, compositor, children, iNextChild=0): particles = compositor.dereference().particles iStartingChild = iNextChild errDesc = None if isinstance(compositor, ModelAll): allParticles = set() # elements required iNextAfterAll = iStartingChild elif isinstance(compositor, ModelChoice): anyChoiceHasMinOccurs0 = False moreParticlesPasses = True while moreParticlesPasses: moreParticlesPasses = False for particle in particles: occurences = 0 if isinstance(particle, (ModelConcept, ModelAny)): elementDeclaration = particle.dereference() while iNextChild < len(children): elt = children[iNextChild] if isinstance(elt, ModelObject): # for any, check namespace overlap if (isinstance(particle, ModelAny) or (elementDeclaration is not None and (elt.qname == elementDeclaration.qname or elt.elementDeclaration.substitutesForQname( elementDeclaration.qname)))): occurences += 1 validate(modelXbrl, elt) iNextChild += 1 if occurences == particle.maxOccurs: break elif not isinstance(particle, ModelAll): break # done with this element else: # comment or processing instruction, skip over it iNextChild += 1 else: # group definition or compositor while occurences < particle.maxOccurs: iPrevChild = iNextChild iNextChild, occured, errDesc, errArgs = validateElementSequence( modelXbrl, particle, children, iNextChild) if occured: occurences += 1 if occurences == particle.maxOccurs or iNextChild >= len( children): break else: break if isinstance(compositor, ModelChoice): if occurences > 0 and particle.minOccurs <= occurences <= particle.maxOccurs: return (iNextChild, True, None, None ) # choice has been selected else: # otherwise start again on next choice if particle.minOccurs == 0: anyChoiceHasMinOccurs0 = True iNextChild = iStartingChild elif isinstance(compositor, ModelAll): if particle.minOccurs <= occurences <= particle.maxOccurs: allParticles.add(particle) # particle found moreParticlesPasses = True break # advance to next all particle elif particle.minOccurs > 0 and errDesc: return (iNextChild, False, errDesc, errArgs) elif not particle.minOccurs <= occurences <= particle.maxOccurs: return (iNextChild, False, ( "xmlSchema:elementOccurencesError", _("%(compositor)s(%(particles)s) %(element)s occured %(occurences)s times, minOccurs=%(minOccurs)s, maxOccurs=%(maxOccurs)s, within %(parentElement)s" )), dict(compositor=compositor, particles=particles, occurences=occurences, minOccurs=particle.minOccursStr, maxOccurs=particle.maxOccursStr)) if isinstance(compositor, ModelAll): missingParticles = set(particles) - allParticles if missingParticles: return (iNextChild, False, ( "xmlSchema:missingParticlesError", _("All(%(particles)s) missing at %(element)s, within %(parentElement)s" )), dict(particles=particles)) occured = True elif isinstance(compositor, ModelChoice): occured = anyChoiceHasMinOccurs0 # deemed to have occured if any choice had minoccurs=0 else: occured = True if isinstance(compositor, ModelType) and iNextChild < len(children): elt = children[iNextChild] eltChildren = elt.modelTupleFacts if isinstance( elt, ModelInlineFact) else elt if any(True for child in eltChildren if isinstance( child, ModelObject)): # any unexpected content elements return (iNextChild, False, ( "xmlSchema:elementUnexpected", _("%(compositor)s(%(particles)s) %(element)s unexpected, within %(parentElement)s" )), dict(compositor=compositor, particles=particles)) return (iNextChild, occured, None, None)